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.
+#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
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
+ 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 */
};
+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 */