summaryrefslogtreecommitdiff
path: root/stats.h
diff options
context:
space:
mode:
Diffstat (limited to 'stats.h')
-rw-r--r--stats.h155
1 files changed, 155 insertions, 0 deletions
diff --git a/stats.h b/stats.h
new file mode 100644
index 0000000..34f492c
--- /dev/null
+++ b/stats.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright IBM Corp. 2008
+ *
+ * Author(s): Martin Peschke <mp3@de.ibm.com>
+ * Stefan Raspl <stefan.raspl@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef STATS_H
+#define STATS_H
+
+#include <linux/types.h>
+#include "endian.h"
+
+struct minmax {
+ __u64 min;
+ __u64 max;
+ __u64 sum;
+ __u64 sos;
+ __u64 num;
+};
+
+static inline void minmax_init(struct minmax *mm)
+{
+ mm->min = -1ULL;
+ mm->max = 0;
+ mm->sum = 0;
+ mm->sos = 0;
+ mm->num = 0;
+}
+
+static inline void minmax_account(struct minmax *mm, __u64 value)
+{
+ mm->sum += value;
+ mm->sos += value * value;
+ if (value < mm->min)
+ mm->min = value;
+ if (value > mm->max)
+ mm->max = value;
+ mm->num++;
+}
+
+static inline void minmax_merge(struct minmax *dst, struct minmax *src)
+{
+ dst->sum += src->sum;
+ dst->sos += src->sos;
+ if (src->min < dst->min)
+ dst->min = src->min;
+ if (src->max > dst->max)
+ dst->max = src->max;
+ dst->num += src->num;
+}
+
+static inline void minmax_to_be(struct minmax *mm)
+{
+ mm->sum = cpu_to_be64(mm->sum);
+ mm->sos = cpu_to_be64(mm->sos);
+ mm->min = cpu_to_be64(mm->min);
+ mm->max = cpu_to_be64(mm->max);
+ mm->num = cpu_to_be64(mm->num);
+}
+
+static inline double minmax_avg(struct minmax *mm)
+{
+ return (mm->sum / (double)mm->num);
+}
+
+static inline double minmax_var(struct minmax *mm)
+{
+ double num = (double)mm->num;
+
+ return ((mm->sos - ((mm->sum * mm->sum) / num)) / num);
+}
+
+static inline int minmax_print(FILE *fp, const char *s, struct minmax *mm)
+{
+ return fprintf(fp, "%s: num %Ld, min %Ld, max %Ld, sum %Ld, squ %Ld, "
+ "avg %.1f, var %.1f\n", s, (unsigned long long)mm->num,
+ (unsigned long long)mm->min, (unsigned long long)mm->max,
+ (unsigned long long)mm->sum, (unsigned long long)mm->sos,
+ minmax_avg(mm), minmax_var(mm));
+}
+
+struct histlog2 {
+ int first;
+ int delta;
+ int num;
+};
+
+static inline __u64 histlog2_upper_limit(int index, struct histlog2 *h)
+{
+ return h->first + (index ? h->delta << (index - 1) : 0);
+}
+
+static inline int histlog2_index(__u64 val, struct histlog2 *h)
+{
+ int i;
+
+ for (i = 0; i < (h->num - 1) && val > histlog2_upper_limit(i, h); i++);
+ return i;
+}
+
+static inline void histlog2_account(__u32 *bucket, __u32 val,
+ struct histlog2 *h)
+{
+ int index = histlog2_index(val, h);
+ bucket[index]++;
+}
+
+static inline void histlog2_merge(struct histlog2 *h, __u32 *dst, __u32 *src)
+{
+ int i;
+
+ for (i = 0; i < h->num - 1; i++)
+ dst[i] += src[i];
+}
+
+static inline void histlog2_to_be(__u32 a[], struct histlog2 *h)
+{
+ int i;
+
+ for (i = 0; i < h->num - 1; i++)
+ a[i] = cpu_to_be32(a[i]);
+}
+
+static inline void histlog2_print(FILE *fp, const char *s, __u32 a[],
+ struct histlog2 *h)
+{
+ int i;
+
+ fprintf(fp, "%s:\n", s);
+ for (i = 0; i < h->num - 1; i++) {
+ fprintf(fp, " %10ld:%6d",
+ (unsigned long)(histlog2_upper_limit(i, h)), a[i]);
+ if (!((i + 1) % 4))
+ fprintf(fp, "\n");
+ }
+ fprintf(fp, " >%8ld:%6d\n",
+ (unsigned long)(histlog2_upper_limit(i - 1, h)), a[i]);
+}
+
+#endif