]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/carp.cc
Cleanup: zap CVS Id tags
[thirdparty/squid.git] / src / carp.cc
index 6d5c212ef9b367466296dce8cee628cf0c546f37..65bec9db0551bb3737cf4fad9673f5ef5d3651a3 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: carp.cc,v 1.20 2002/10/13 20:34:59 robertc Exp $
+ * $Id$
  *
  * DEBUG: section 39    Cache Array Routing Protocol
  * AUTHOR: Henrik Nordstrom
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
  *  (at your option) any later version.
- *  
+ *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *  
+ *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  */
 
 #include "squid.h"
+#include "CacheManager.h"
 #include "Store.h"
 
-#if USE_CARP
-
 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
 
 static int n_carp_peers = 0;
@@ -48,10 +47,18 @@ static OBJH carpCachemgr;
 static int
 peerSortWeight(const void *a, const void *b)
 {
-    const peer *const *p1 = a, *const *p2 = b;
+    const peer *const *p1 = (const peer *const *)a;
+    const peer *const *p2 = (const peer *const *)b;
     return (*p1)->weight - (*p2)->weight;
 }
 
+static void
+carpRegisterWithCacheManager(void)
+{
+    CacheManager::GetInstance()->
+    registerAction("carp", "CARP information", carpCachemgr, 0, 1);
+}
+
 void
 carpInit(void)
 {
@@ -63,45 +70,69 @@ carpInit(void)
     peer **P;
     char *t;
     /* Clean up */
+
     for (k = 0; k < n_carp_peers; k++) {
-       cbdataReferenceDone(carp_peers[k]);
+        cbdataReferenceDone(carp_peers[k]);
     }
+
     safe_free(carp_peers);
     n_carp_peers = 0;
+
+    /* initialize cache manager before we have a chance to leave the execution path */
+    carpRegisterWithCacheManager();
+
     /* find out which peers we have */
+
     for (p = Config.peers; p; p = p->next) {
-       if (!p->options.carp)
-           continue;
-       assert(p->type == PEER_PARENT);
-       if (p->weight == 0)
-           continue;
-       n_carp_peers++;
-       W += p->weight;
+        if (!p->options.carp)
+            continue;
+
+        assert(p->type == PEER_PARENT);
+
+        if (p->weight == 0)
+            continue;
+
+        n_carp_peers++;
+
+        W += p->weight;
     }
+
     if (n_carp_peers == 0)
-       return;
-    carp_peers = xcalloc(n_carp_peers, sizeof(*carp_peers));
+        return;
+
+    carp_peers = (peer **)xcalloc(n_carp_peers, sizeof(*carp_peers));
+
     /* Build a list of the found peers and calculate hashes and load factors */
     for (P = carp_peers, p = Config.peers; p; p = p->next) {
-       if (!p->options.carp)
-           continue;
-       if (p->weight == 0)
-           continue;
-       /* calculate this peers hash */
-       p->carp.hash = 0;
-       for (t = p->host; *t != 0; t++)
-           p->carp.hash += ROTATE_LEFT(p->carp.hash, 19) + (unsigned int) *t;
-       p->carp.hash += p->carp.hash * 0x62531965;
-       p->carp.hash = ROTATE_LEFT(p->carp.hash, 21);
-       /* and load factor */
-       p->carp.load_factor = ((double) p->weight) / (double) W;
-       if (floor(p->carp.load_factor * 1000.0) == 0.0)
-           p->carp.load_factor = 0.0;
-       /* add it to our list of peers */
-       *P++ = cbdataReference(p);
+        if (!p->options.carp)
+            continue;
+
+        if (p->weight == 0)
+            continue;
+
+        /* calculate this peers hash */
+        p->carp.hash = 0;
+
+        for (t = p->name; *t != 0; t++)
+            p->carp.hash += ROTATE_LEFT(p->carp.hash, 19) + (unsigned int) *t;
+
+        p->carp.hash += p->carp.hash * 0x62531965;
+
+        p->carp.hash = ROTATE_LEFT(p->carp.hash, 21);
+
+        /* and load factor */
+        p->carp.load_factor = ((double) p->weight) / (double) W;
+
+        if (floor(p->carp.load_factor * 1000.0) == 0.0)
+            p->carp.load_factor = 0.0;
+
+        /* add it to our list of peers */
+        *P++ = cbdataReference(p);
     }
+
     /* Sort our list on weight */
     qsort(carp_peers, n_carp_peers, sizeof(*carp_peers), peerSortWeight);
+
     /* Calculate the load factor multipliers X_k
      *
      * X_1 = pow ((K*p_1), (1/K))
@@ -111,24 +142,27 @@ carpInit(void)
      * simplified to have X_1 part of the loop
      */
     K = n_carp_peers;
+
     P_last = 0.0;              /* Empty P_0 */
+
     Xn = 1.0;                  /* Empty starting point of X_1 * X_2 * ... * X_{x-1} */
+
     X_last = 0.0;              /* Empty X_0, nullifies the first pow statement */
+
     for (k = 1; k <= K; k++) {
-       double Kk1 = (double) (K - k + 1);
-       p = carp_peers[k - 1];
-       p->carp.load_multiplier = (Kk1 * (p->carp.load_factor - P_last)) / Xn;
-       p->carp.load_multiplier += pow(X_last, Kk1);
-       p->carp.load_multiplier = pow(p->carp.load_multiplier, 1.0 / Kk1);
-       Xn *= p->carp.load_multiplier;
-       X_last = p->carp.load_multiplier;
-       P_last = p->carp.load_factor;
+        double Kk1 = (double) (K - k + 1);
+        p = carp_peers[k - 1];
+        p->carp.load_multiplier = (Kk1 * (p->carp.load_factor - P_last)) / Xn;
+        p->carp.load_multiplier += pow(X_last, Kk1);
+        p->carp.load_multiplier = pow(p->carp.load_multiplier, 1.0 / Kk1);
+        Xn *= p->carp.load_multiplier;
+        X_last = p->carp.load_multiplier;
+        P_last = p->carp.load_factor;
     }
-    cachemgrRegister("carp", "CARP information", carpCachemgr, 0, 1);
 }
 
 peer *
-carpSelectParent(request_t * request)
+carpSelectParent(HttpRequest * request)
 {
     int k;
     const char *c;
@@ -141,30 +175,35 @@ carpSelectParent(request_t * request)
     const char *key = NULL;
 
     if (n_carp_peers == 0)
-       return NULL;
+        return NULL;
 
     key = urlCanonical(request);
 
     /* calculate hash key */
-    debug(39, 2) ("carpSelectParent: Calculating hash for %s\n", key);
+    debugs(39, 2, "carpSelectParent: Calculating hash for " << key);
+
     for (c = key; *c != 0; c++)
-       user_hash += ROTATE_LEFT(user_hash, 19) + *c;
+        user_hash += ROTATE_LEFT(user_hash, 19) + *c;
+
     /* select peer */
     for (k = 0; k < n_carp_peers; k++) {
-       tp = carp_peers[k];
-       combined_hash = (user_hash ^ tp->carp.hash);
-       combined_hash += combined_hash * 0x62531965;
-       combined_hash = ROTATE_LEFT(combined_hash, 21);
-       score = combined_hash * tp->carp.load_multiplier;
-       debug(39, 3) ("carpSelectParent: %s combined_hash %u score %.0f\n",
-           tp->host, combined_hash, score);
-       if ((score > high_score) && peerHTTPOkay(tp, request)) {
-           p = tp;
-           high_score = score;
-       }
+        tp = carp_peers[k];
+        combined_hash = (user_hash ^ tp->carp.hash);
+        combined_hash += combined_hash * 0x62531965;
+        combined_hash = ROTATE_LEFT(combined_hash, 21);
+        score = combined_hash * tp->carp.load_multiplier;
+        debugs(39, 3, "carpSelectParent: " << tp->name << " combined_hash " << combined_hash  <<
+               " score " << std::setprecision(0) << score);
+
+        if ((score > high_score) && peerHTTPOkay(tp, request)) {
+            p = tp;
+            high_score = score;
+        }
     }
+
     if (p)
-       debug(39, 2) ("carpSelectParent: selected %s\n", p->host);
+        debugs(39, 2, "carpSelectParent: selected " << p->name);
+
     return p;
 }
 
@@ -174,20 +213,20 @@ carpCachemgr(StoreEntry * sentry)
     peer *p;
     int sumfetches = 0;
     storeAppendPrintf(sentry, "%24s %10s %10s %10s %10s\n",
-       "Hostname",
-       "Hash",
-       "Multiplier",
-       "Factor",
-       "Actual");
+                      "Hostname",
+                      "Hash",
+                      "Multiplier",
+                      "Factor",
+                      "Actual");
+
     for (p = Config.peers; p; p = p->next)
-       sumfetches += p->stats.fetches;
+        sumfetches += p->stats.fetches;
+
     for (p = Config.peers; p; p = p->next) {
-       storeAppendPrintf(sentry, "%24s %10x %10f %10f %10f\n",
-           p->host, p->carp.hash,
-           p->carp.load_multiplier,
-           p->carp.load_factor,
-           sumfetches ? (double) p->stats.fetches / sumfetches : -1.0);
+        storeAppendPrintf(sentry, "%24s %10x %10f %10f %10f\n",
+                          p->name, p->carp.hash,
+                          p->carp.load_multiplier,
+                          p->carp.load_factor,
+                          sumfetches ? (double) p->stats.fetches / sumfetches : -1.0);
     }
 }
-
-#endif