home *** CD-ROM | disk | FTP | other *** search
/ ftp.ee.lbl.gov / 2014.05.ftp.ee.lbl.gov.tar / ftp.ee.lbl.gov / acld-1.11.tar.gz / acld-1.11.tar / acld-1.11 / stats.c < prev    next >
C/C++ Source or Header  |  2012-01-18  |  4KB  |  181 lines

  1. /*
  2.  * Copyright (c) 2007, 2008, 2010, 2011, 2012
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static const char rcsid[] =
  24.     "@(#) $Id: stats.c 804 2012-01-18 08:45:27Z leres $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/types.h>
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <syslog.h>
  33.  
  34. #include "acld.h"
  35. #include "util.h"
  36.  
  37. static long now = 0;
  38.  
  39. /* Forwards */
  40. static int stats_bucket(struct stats *);
  41. static void stats_now(void);
  42. static void stats_updateptrs(struct stats *);
  43.  
  44. /* Return index to bucket defined by the specificed time */
  45. static int
  46. stats_bucket(struct stats *st)
  47. {
  48.  
  49.     return ((now % (st->len * st->secs)) / st->secs);
  50. }
  51.  
  52. void
  53. stats_free(struct stats *st)
  54. {
  55.  
  56.     if (st->buckets != NULL)
  57.         free(st->buckets);
  58.     memset(st, 0, sizeof(*st));
  59. }
  60.  
  61. int
  62. stats_gethiwater(struct stats *st)
  63. {
  64.     int i, hiwater;
  65.     struct bucket *p;
  66.  
  67.     if (st->buckets == NULL)
  68.         return (0);
  69.  
  70.     /* Update pointers and potentially zero out stale data */
  71.     stats_updateptrs(st);
  72.  
  73.     hiwater = 0;
  74.     for (i = 0, p = st->buckets; i < st->len; ++i, ++p)
  75.         if (hiwater < p->hiwater)
  76.             hiwater = p->hiwater;
  77.     return (hiwater);
  78. }
  79.  
  80. /* Returns rate in packets/min */
  81. int
  82. stats_getrate(struct stats *st, const char *what)
  83. {
  84.     int i, count, secs;
  85.     struct bucket *p;
  86.  
  87.     if (st->buckets == NULL)
  88.         return (0);
  89.  
  90.     /* Update pointers and potentially zero out stale data */
  91.     stats_updateptrs(st);
  92.  
  93.     /*
  94.      * Calculate the seconds in current bucket plus seconds for
  95.      * the other buckets
  96.      */
  97.     secs = ((now % (st->len * st->secs)) % st->secs) +
  98.         ((st->len - 1) * st->secs);
  99.  
  100.     count = 0;
  101.     for (i = 0, p = st->cur; i < st->len; ++i, ++p) {
  102.         if (p >= st->buckets + st->len)
  103.             p = st->buckets;
  104.         count += p->count;
  105.     }
  106.     lg(LOG_DEBUG, "stats_rate: %s %d/%d seconds (%d/(%d/60) == %f/min)",
  107.         what,
  108.         secs, (int)st->len * st->secs,
  109.         count, secs,
  110.         ((secs == 0) ? 0.0 : (double)count / (((double)secs) / 60.0)));
  111.     return ((secs == 0) ? 0 : (count * 60) / secs);
  112. }
  113.  
  114. /*
  115.  * Passed in the number of buckets and width in seconds of each
  116.  */
  117. void
  118. stats_init(struct stats *st, size_t len, int secs, const char *what)
  119. {
  120.     if (len < 1)
  121.         abort();
  122.     stats_free(st);
  123.     st->len = len;
  124.     st->secs = secs;
  125.     st->buckets = new(len, sizeof(*st->buckets), what);
  126.     st->cur = st->buckets;
  127.     stats_now();
  128.     st->cur += stats_bucket(st);
  129.     st->lasttime = now;
  130. }
  131.  
  132. static void
  133. stats_now()
  134. {
  135.     struct timeval tv;
  136.  
  137.     getts(&tv);
  138.     now = tv.tv_sec;
  139. }
  140.  
  141. /* This gets called when an an addition is made */
  142. void
  143. stats_sethiwater(struct stats *st, int len)
  144. {
  145.  
  146.     /* Update pointers and potentially zero out stale data */
  147.     stats_updateptrs(st);
  148.     if (st->cur->hiwater < len)
  149.         st->cur->hiwater = len;
  150. }
  151.  
  152. /* This gets called when a block or nullzero is added */
  153. void
  154. stats_setrate(struct stats *st)
  155. {
  156.  
  157.     /* Update pointers and potentially zero out stale data */
  158.     stats_updateptrs(st);
  159.     ++st->cur->count;
  160. }
  161.  
  162. static void
  163. stats_updateptrs(struct stats *st)
  164. {
  165.     int i;
  166.     struct bucket *p;
  167.  
  168.     /* XXX if now - lasttime is big enough we should zero everything */
  169.     stats_now();
  170.     i = stats_bucket(st);
  171.     p = st->buckets + i;
  172.     while (p != st->cur) {
  173.         ++st->cur;
  174.         if (st->cur >= st->buckets + st->len)
  175.             st->cur = st->buckets;
  176.         st->cur->count = 0;
  177.         st->cur->hiwater = 0;
  178.     }
  179.     st->lasttime = now;
  180. }
  181.