On Wed, May 16, 2012 at 05:16:40PM +0200, Nikola Pajkovsky wrote:
Vitezslav Samel <vitezslav(a)samel.cz> writes:
> These functions compute and print (simple) moving average
> of rate of some activity (be it interface activity in
> bytes per sec, packets per sec, etc.).
>
> Signed-off-by: Vitezslav Samel <vitezslav(a)samel.cz>
> ---
> Makefile | 2 +
> src/rate.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> src/rate.h | 33 ++++++++++++++++++++
> 3 files changed, 135 insertions(+), 0 deletions(-)
> create mode 100644 src/rate.c
> create mode 100644 src/rate.h
>
> diff --git a/src/rate.c b/src/rate.c
> new file mode 100644
> index 0000000..70d2da8
> --- /dev/null
> +++ b/src/rate.c
> @@ -0,0 +1,100 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <sys/time.h>
includes are in iptraf-ng-compat.h. dont reinclude them.
OK.
> +#include "rate.h"
> +#include "iptraf-ng-compat.h"
> +
> +void rate_init(struct rate *rate, unsigned int n)
> +{
> + if (rate) {
> + rate->n = n;
> + rate->index = 0;
> + rate->sma = 0;
> + rate->rates = xmallocz(n * sizeof(*rate->rates));
> + }
> +}
I don't like that 'if (rate) {} end-func' please use simpler version
I prefer to have one entry and one exit point from such small
function, but will follow your style.
void rate_init(struct rate *rate, unsigned int n)
{
if (!rate)
return;
rate->n = n;
rate->index = 0;
rate->sma = 0;
rate->rates = xmallocz(n * sizeof(*rate->rates));
}
> +void rate_destroy(struct rate *rate)
> +{
> + if (rate) {
> + if (rate->rates) {
> + free(rate->rates);
> + rate->rates = NULL;
> + }
> + rate->n = 0;
> + }
> +}
Now you have to nasted if's!
void rate_destroy(struct rate *rate)
{
if (!rate)
return;
rate->n = 0;
if (!rate->rates)
return;
free(rate->rates);
rate->rates = NULL;
}
> +void rate_add_rate(struct rate *rate, unsigned long bytes,
> + unsigned long msecs)
> +{
> + if (rate) {
> + rate->rates[rate->index] = bytes * 1000ULL / msecs;
> + rate->index = (rate->index + 1) % rate->n;
> +
> + /* compute the moving average */
> + unsigned long long sum = 0;
> + for(unsigned int i = 0; i < rate->n; i++)
> + sum += rate->rates[i];
> + rate->sma = sum / rate->n;
> + }
> +}
ditto with if's
> +unsigned long rate_get_average(struct rate *rate)
> +{
> + if (rate)
> + return rate->sma;
> + else
> + return 0UL;
> +}
> +
> +int rate_print(unsigned long rate, int dispmode, char *buf, unsigned n)
> +{
> + char *suffix[] = { "k", "M", "G", "T",
"P", "E", "Z", "Y" };
> + unsigned n_suffix = sizeof(suffix) / sizeof(suffix[0]);
add #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) to iptraf-ng-compat.h
and use it
OK.
> + int chars;
> +
> + if (dispmode == KBITS) {
> + unsigned long tmp = rate;
> + unsigned int i = 0;
> + unsigned long divider = 1000;
> +
> + rate *= 8;
> + while(tmp >= 100000000) {
> + tmp /= 1000;
> + i++;
> + divider *= 1000;
> + }
> + if (i >= n_suffix)
> + chars = snprintf(buf, n, "error");
> + else
> + chars = snprintf(buf, n, "%9.2f %sbps", (double)rate / divider,
suffix[i]);
> + } else {
> + unsigned int i = 0;
> +
> + while(rate > 99 * (1UL << 20)) {
> + rate >>= 10;
> + i++;
> + }
> + if (i >= n_suffix)
> + chars = snprintf(buf, n, "error");
> + else
> + chars = snprintf(buf, n, "%9.2f %sBps", (double)rate / 1024,
suffix[i]);
> + }
> + buf[n - 1] = '\0';
> +
> + return chars;
> +}
> +
> +int rate_print_pps(unsigned long rate, char *buf, unsigned n)
> +{
> + int chars;
> +
> + chars = snprintf(buf, n, "%9lu pps", rate);
> + buf[n - 1] = '\0';
> +
> + return chars;
> +}
> diff --git a/src/rate.h b/src/rate.h
> new file mode 100644
> index 0000000..484ae90
> --- /dev/null
> +++ b/src/rate.h
> @@ -0,0 +1,33 @@
> +#ifndef IPTRAF_NG_RATE_H
> +#define IPTRAF_NG_RATE_H
> +
> +#include <sys/time.h>
> +
> +/* SMA = Simple Moving Average */
> +
> +/*
> + * SMA = (p(M) + p(M-1) + ... + p(M-n-1)) / n
> + *
> + * or
> + *
> + * SMA = last_SMA - (p(M-n) / n) + (p(M) / n)
> + */
> +
> +struct rate {
> + unsigned int n; /* number of elements */
> + unsigned int index; /* index into the values array */
> +
> + unsigned long long *rates; /* units are: bytes per second */
> +
> + unsigned long sma; /* simple moving average */
> +};
align names and comments
struct rate {
unsigned int n; /* number of elements */
unsigned int index; /* index into the values array */
unsigned long long *rates; /* units are: bytes per second */
unsigned long sma; /* simple moving average */
};
OK.
> +void rate_init(struct rate *rate, unsigned int n);
> +void rate_destroy(struct rate *rate);
> +void rate_add_rate(struct rate *rate, unsigned long bytes,
> + unsigned long msecs);
> +unsigned long rate_get_average(struct rate *rate);
> +int rate_print(unsigned long rate, int dispmode, char *buf, unsigned n);
> +int rate_print_pps(unsigned long rate, char *buf, unsigned n);
> +
> +#endif /* IPTRAF_NG_RATE_H */
Vita