patch for kbytes-transferred stats error

From: Lincoln Dale <ltd@dont-contact.us>
Date: Sat, 31 Jan 1998 23:26:09 +0800

whilst coding some experiemental alternatives to the current
expiry policy within squid, some regression testing revealed
an error in the reporting (to cachemgr) of the kbytes
transferred figure.

when recording kbytes transferred, it stores the value rounded
to kbytes, rather than bytes. the net-effect on the distribution
of objects within my trial cache (with mean object-size of 12.3kbytes)
was an under-reporting of the byte-hit-rate of 3% - quite significant.

the following patches (to squid-1.1.20 and squid-1.2beta11) fixes this
by keeping the per-item-counter in bytes, and only rounds to kbytes
for the total-counter. due to this being able to only handle up to
4096gb (reachable in the uptime of large caches), i've also added
code for handling counter-rollover-due-to-maxint.

patch to 1.1.20:
--- begin patch ---
*** stat.h 1998/01/31 14:28:14 1.1
--- stat.h 1998/01/31 14:33:58 1.2
***************
*** 126,131 ****
--- 126,132 ----
      float hitratio;
      unsigned int transferrate;
      unsigned int refcount;
+ unsigned int transferbyte_rollover;
      unsigned int transferbyte;
  
  } proto_stat;
*** stat.c 1998/01/31 14:27:21 1.1
--- stat.c 1998/01/31 14:45:07 1.2
***************
*** 176,181 ****
--- 176,182 ----
      proto_stat *p = &obj->proto_stat_data[PROTO_MAX];
      proto_stat *q = NULL;
      int secs = 0;
+ float f = 0;
  
      secs = (int) (squid_curtime - squid_starttime);
      storeAppendPrintf(sentry, "{ %s\n", desc); /* } */
***************
*** 189,194 ****
--- 190,196 ----
      p->miss = 0;
      p->refcount = 0;
      p->transferbyte = 0;
+ p->transferbyte_rollover = 0;
      /* find the total */
      for (proto_id = PROTO_NONE; proto_id < PROTO_MAX; ++proto_id) {
          q = &obj->proto_stat_data[proto_id];
***************
*** 200,206 ****
          p->hit += q->hit;
          p->miss += q->miss;
          p->refcount += q->refcount;
! p->transferbyte += q->transferbyte;
      }
      /* dump it */
      for (proto_id = PROTO_NONE; proto_id <= PROTO_MAX; ++proto_id) {
--- 202,212 ----
          p->hit += q->hit;
          p->miss += q->miss;
          p->refcount += q->refcount;
! p->transferbyte_rollover += q->transferbyte_rollover;
! p->transferbyte += q->transferbyte;
! /* check for rollover */
! if (p->transferbyte < q->transferbyte)
! p->transferbyte_rollover++;
      }
      /* dump it */
      for (proto_id = PROTO_NONE; proto_id <= PROTO_MAX; ++proto_id) {
***************
*** 211,226 ****
                  ((float) p->hit +
                  (float) p->miss);
          }
! storeAppendPrintf(sentry, "{%8.8s %d %d %d %d %4.2f %d %d %d}\n",
              p->protoname,
              p->object_count,
              p->kb.max,
              p->kb.now,
              p->kb.min,
              p->hitratio,
! (secs ? p->transferbyte / secs : 0),
              p->refcount,
! p->transferbyte);
      }
      storeAppendPrintf(sentry, close_bracket);
  }
--- 217,236 ----
                  ((float) p->hit +
                  (float) p->miss);
          }
! f =
! ( ((float) p->transferbyte_rollover * (float) UINT_MAX) +
! (float) p->transferbyte) /
! (float) 1024;
! storeAppendPrintf(sentry, "{%8.8s %d %d %d %d %4.2f %0.0f %d %0.0f}\n",
              p->protoname,
              p->object_count,
              p->kb.max,
              p->kb.now,
              p->kb.min,
              p->hitratio,
! (secs ? f / secs : 0),
              p->refcount,
! f);
      }
      storeAppendPrintf(sentry, close_bracket);
  }
***************
*** 1296,1302 ****
  proto_touchobject(cacheinfo * obj, protocol_t proto_id, int size)
  {
      obj->proto_stat_data[proto_id].refcount++;
! obj->proto_stat_data[proto_id].transferbyte += (1023 + size) >> 10;
  }
  
  static void
--- 1306,1315 ----
  proto_touchobject(cacheinfo * obj, protocol_t proto_id, int size)
  {
      obj->proto_stat_data[proto_id].refcount++;
! obj->proto_stat_data[proto_id].transferbyte += size;
! /* check for rollover */
! if (obj->proto_stat_data[proto_id].transferbyte < size)
! obj->proto_stat_data[proto_id].transferbyte_rollover++;
  }
  
  static void
***************
*** 1385,1390 ****
--- 1398,1404 ----
          obj->proto_stat_data[i].hitratio = 0.0;
          obj->proto_stat_data[i].transferrate = 0;
          obj->proto_stat_data[i].refcount = 0;
+ obj->proto_stat_data[i].transferbyte_rollover = 0;
          obj->proto_stat_data[i].transferbyte = 0;
          obj->proto_stat_data[i].kb.max = 0;
          obj->proto_stat_data[i].kb.min = 0;
--- end patch ---

for squid-1.2 betas, the patch is similar (base squid-1.2beta11):
--- begin patch ---
*** structs.h 1998/01/31 09:57:39 1.1
--- structs.h 1998/01/31 09:58:30 1.2
***************
*** 756,761 ****
--- 756,762 ----
      float hitratio;
      unsigned int transferrate;
      unsigned int refcount;
+ unsigned int transferbyte_rollover;
      unsigned int transferbyte;
  };
  
*** stat.c 1998/01/31 09:55:22 1.1
--- stat.c 1998/01/31 09:59:42 1.2
***************
*** 137,142 ****
--- 137,144 ----
      proto_stat *p = &obj->proto_stat_data[PROTO_MAX];
      proto_stat *q = NULL;
      int secs = 0;
+ float f = 0;
+
      secs = (int) (squid_curtime - squid_start.tv_sec);
      storeAppendPrintf(sentry, "{ %s\n", desc); /* } */
      strcpy(p->protoname, "TOTAL");
***************
*** 149,154 ****
--- 151,157 ----
      p->miss = 0;
      p->refcount = 0;
      p->transferbyte = 0;
+ p->transferbyte_rollover = 0;
      /* find the total */
      for (proto_id = PROTO_NONE; proto_id < PROTO_MAX; ++proto_id) {
          q = &obj->proto_stat_data[proto_id];
***************
*** 160,166 ****
          p->hit += q->hit;
          p->miss += q->miss;
          p->refcount += q->refcount;
! p->transferbyte += q->transferbyte;
      }
      /* dump it */
      for (proto_id = PROTO_NONE; proto_id <= PROTO_MAX; ++proto_id) {
--- 163,173 ----
          p->hit += q->hit;
          p->miss += q->miss;
          p->refcount += q->refcount;
! p->transferbyte_rollover += q->transferbyte_rollover;
! p->transferbyte += q->transferbyte;
! /* check for rollover */
! if (p->transferbyte < q->transferbyte)
! p->transferbyte_rollover++;
      }
      /* dump it */
      for (proto_id = PROTO_NONE; proto_id <= PROTO_MAX; ++proto_id) {
***************
*** 171,186 ****
                  ((float) p->hit +
                  (float) p->miss);
          }
! storeAppendPrintf(sentry, "{%8.8s %d %d %d %d %4.2f %d %d %d}\n",
              p->protoname,
              p->object_count,
              p->kb.max,
              p->kb.now,
              p->kb.min,
              p->hitratio,
! (secs ? p->transferbyte / secs : 0),
              p->refcount,
! p->transferbyte);
      }
      storeAppendPrintf(sentry, close_bracket);
  }
--- 178,197 ----
                  ((float) p->hit +
                  (float) p->miss);
          }
! f =
! ( ((float) p->transferbyte_rollover * (float) MAXINT) +
! (float) p->transferbyte) /
! (float) 1024;
! storeAppendPrintf(sentry, "{%8.8s %d %d %d %d %4.2f %0.0f %d %0.0f}\n",
              p->protoname,
              p->object_count,
              p->kb.max,
              p->kb.now,
              p->kb.min,
              p->hitratio,
! (secs ? f / (float) secs : 0),
              p->refcount,
! f);
      }
      storeAppendPrintf(sentry, close_bracket);
  }
***************
*** 783,789 ****
  proto_touchobject(cacheinfo * obj, protocol_t proto_id, int size)
  {
      obj->proto_stat_data[proto_id].refcount++;
! obj->proto_stat_data[proto_id].transferbyte += (1023 + size) >> 10;
  }
  
  static void
--- 794,803 ----
  proto_touchobject(cacheinfo * obj, protocol_t proto_id, int size)
  {
      obj->proto_stat_data[proto_id].refcount++;
! obj->proto_stat_data[proto_id].transferbyte += size;
! /* check for rollover */
! if (obj->proto_stat_data[proto_id].transferbyte < size)
! obj->proto_stat_data[proto_id].transferbyte_rollover++;
  }
  
  static void
***************
*** 850,855 ****
--- 864,870 ----
          obj->proto_stat_data[i].hitratio = 0.0;
          obj->proto_stat_data[i].transferrate = 0;
          obj->proto_stat_data[i].refcount = 0;
+ obj->proto_stat_data[i].transferbyte_rollover = 0;
          obj->proto_stat_data[i].transferbyte = 0;
          obj->proto_stat_data[i].kb.max = 0;
          obj->proto_stat_data[i].kb.min = 0;
--- end patch ---

cheers,

lincoln.
Received on Sat Jan 31 1998 - 07:34:10 MST

This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:38:35 MST