]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
A number of CARP bug fixes.
authorwessels <>
Tue, 5 Dec 2000 17:10:57 +0000 (17:10 +0000)
committerwessels <>
Tue, 5 Dec 2000 17:10:57 +0000 (17:10 +0000)
peer->carp.hash was an unsigned long, but the spec requires 32-bit math
on integers.  Since longs are known to sometimes be 64-bits, its safer
to use unsigned int.

peer->carp.load_factor was a float, but its better to use double to
be consistent with other floating point functions and variables.

In parse_peer() I'm concerned that *token could be signed, so its
now casted to unsigned int.

In parse_peer() there is a bug in calculating the proxy hostname hash.
On the final ROTATE_LEFT, it should be "=" rather than "+=".

In carpInit() pay special attention to int/double conversion bugs
and passing ints to functions that expect doubles.

In carpInit() there is a bug with the value of "k".  In the loop,
k needs to be incremented *before* its used.  The internet-draft
begins with k=1, so the first time through the loop k should equal 2.

Added "carp" to cache manager for info and debugging.

I think there are still two bugs: (1) the draft says the multipliers
must be calculated in order of smallest to largest factor.  We don't
do that yet. (2) the 'score' calculation needs to be converted to
double when we multiply by the multiplier.  Otherwise there will
be overflows since the multiplier can be greater than 1.

src/cache_cf.cc
src/carp.cc
src/structs.h

index a59446588e660ab0d8c93df9a8af5421192d527f..7a77bff1c5bb47afba202713e1518407c5e5ff0a 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.cc,v 1.359 2000/12/05 08:55:47 wessels Exp $
+ * $Id: cache_cf.cc,v 1.360 2000/12/05 10:10:57 wessels Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -1106,14 +1106,14 @@ parse_peer(peer ** head)
     p->tcp_up = PEER_TCP_MAGIC_COUNT;
     p->test_fd = -1;
 #if USE_CARP
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> ((sizeof(u_long)*8)-(n))))
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
     if (p->carp.load_factor) {
        /* calculate this peers hash for use in CARP */
        p->carp.hash = 0;
        for (token = p->host; *token != 0; token++)
-           p->carp.hash += ROTATE_LEFT(p->carp.hash, 19) + *token;
+           p->carp.hash += ROTATE_LEFT(p->carp.hash, 19) + (unsigned int) *token;
        p->carp.hash += p->carp.hash * 0x62531965;
-       p->carp.hash += ROTATE_LEFT(p->carp.hash, 21);
+       p->carp.hash = ROTATE_LEFT(p->carp.hash, 21);
     }
 #endif
     /* This must preceed peerDigestCreate */
index 1771229eefa6355c62bed378745cf3bf126c9f91..c0c0de61d4365968123bc178c79a3652fec9abe7 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: carp.cc,v 1.13 2000/10/20 23:50:59 hno Exp $
+ * $Id: carp.cc,v 1.14 2000/12/05 10:10:57 wessels Exp $
  *
  * DEBUG: section 39    Cache Array Routing Protocol
  * AUTHOR: Eric Stern
 
 #if USE_CARP
 
+static OBJH carpCachemgr;
+
 void
 carpInit(void)
 {
     /* calculate load factors */
     int K = 0;
-    float a = 0.0;
-    float Xn;
-    float P_last;
-    float X_last;
+    double a = 0.0;
+    double dJ;
+    double Xn;
+    double P_last;
+    double X_last;
     int k;
     peer *p;
     for (p = Config.peers; p; p = p->next) {
@@ -54,7 +57,7 @@ carpInit(void)
     }
     if (a == 0.0) {
        for (p = Config.peers; p; p = p->next)
-           p->carp.load_multiplier = 1;
+           p->carp.load_multiplier = 1.0;
        return;
     }
     /*
@@ -66,21 +69,23 @@ carpInit(void)
     k = 1;
     P_last = 0;
     p = Config.peers;
-    p->carp.load_multiplier = pow(K * p->carp.load_factor, 1 / K);
+    p->carp.load_multiplier = pow(p->carp.load_factor * K, 1.0 / K);
     Xn = p->carp.load_multiplier;
     P_last = p->carp.load_factor;
     X_last = p->carp.load_multiplier;
     if (!p->next)
        return;
     for (p = p->next; p; p = p->next) {
-       p->carp.load_multiplier = ((K - k + 1) * (p->carp.load_factor - P_last)) / Xn;
-       p->carp.load_multiplier += pow(X_last, K - k + 1);
-       p->carp.load_multiplier = pow(p->carp.load_multiplier, 1 / (K - k + 1));
+       k++;
+       dJ = (double) (K - k + 1);
+       p->carp.load_multiplier = (dJ * (p->carp.load_factor - P_last)) / Xn;
+       p->carp.load_multiplier += pow(X_last, dJ);
+       p->carp.load_multiplier = pow(p->carp.load_multiplier, 1 / dJ);
        Xn *= p->carp.load_multiplier;
        X_last = p->carp.load_multiplier;
-       k++;
        P_last = p->carp.load_factor;
     }
+    cachemgrRegister("carp", "CARP information", carpCachemgr, 0, 1);
 }
 
 peer *
@@ -120,4 +125,28 @@ carpSelectParent(request_t * request)
        debug(39, 3) ("carpSelectParent: selected CARP %s\n", p->host);
     return p;
 }
+
+static void
+carpCachemgr(StoreEntry * sentry)
+{
+    peer *p;
+    int sumfetches = 0;
+    storeAppendPrintf(sentry, "%24s %10s %10s %10s %10s\n",
+       "Hostname",
+       "Hash",
+       "Multiplier",
+       "Factor",
+       "Actual");
+    for (p = Config.peers; p; p = p->next)
+       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);
+    }
+
+}
+
 #endif
index 48285050d0e47cab92d580d887667317f3166341..05b8fe4165fbfb5234ac5b4fa0fd69d3562d959c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.363 2000/12/05 09:16:00 wessels Exp $
+ * $Id: structs.h,v 1.364 2000/12/05 10:10:59 wessels Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -1103,8 +1103,8 @@ struct _peer {
     int test_fd;
 #if USE_CARP
     struct {
-       unsigned long hash;
-       unsigned long load_multiplier;
+       unsigned int hash;
+       double load_multiplier;
        float load_factor;
     } carp;
 #endif