/*
 * 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 "blktrace.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)
{
	if (!mm->num)
		return 0;

	return (mm->sum / (double)mm->num);
}

static inline double minmax_var(struct minmax *mm)
{
	double num = (double)mm->num;

	if (!mm->num)
		return 0;

	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; i++)
		dst[i] += src[i];
}

static inline void histlog2_to_be(__u32 a[], struct histlog2 *h)
{
	int i;

	for (i = 0; i < h->num; 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
