-
/*
- * DEBUG: section 62 Generic Histogram
- * AUTHOR: Duane Wessels
- *
- * SQUID Web Proxy Cache http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from
- * the Internet community; see the CONTRIBUTORS file for full
- * details. Many organizations have provided support for Squid's
- * development; see the SPONSORS file for full details. Squid is
- * Copyrighted (C) 2001 by the Regents of the University of
- * California; see the COPYRIGHT file for full details. Squid
- * incorporates software developed and/or copyrighted by other
- * sources; see the CREDITS file for full details.
- *
- * 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, USA.
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
*
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
*/
-#include "config.h"
+/* DEBUG: section 62 Generic Histogram */
+
+#include "squid.h"
#include "StatHist.h"
+#include <cmath>
+
/* Local functions */
static StatHistBinDumper statHistBinDumper;
/* low level init, higher level functions has less params */
void
-StatHist::init(int capacity_, hbase_f * val_in_, hbase_f * val_out_, double min_, double max_)
+StatHist::init(unsigned int newCapacity, hbase_f * val_in_, hbase_f * val_out_, double newMin, double newMax)
{
- assert(capacity_ > 0);
- assert(val_in_ && val_out_);
- /* check before we divide to get scale */
- assert(val_in_(max_ - min_) > 0);
- min = min_;
- max = max_;
- capacity = capacity_;
+ /* check before we divide to get scale_ */
+ assert(val_in_(newMax - newMin) > 0);
+ min_ = newMin;
+ max_ = newMax;
+ capacity_ = newCapacity;
val_in = val_in_;
val_out = val_out_;
- bins = static_cast<int *>(xcalloc(capacity, sizeof(int)));
- scale = capacity / val_in(max - min);
-
- /* check that functions are valid */
- /* a min value should go into bin[0] */
- assert(findBin(min) == 0);
- /* a max value should go into the last bin */
- assert(findBin(max) == capacity - 1);
- /* it is hard to test val_out, here is a crude test */
- assert(((int) floor(0.99 + val(0) - min)) == 0);
+ bins = static_cast<bins_type *>(xcalloc(capacity_, sizeof(bins_type)));
+ scale_ = capacity_ / val_in(max_ - min_);
}
-void
-StatHist::clear()
+StatHist::StatHist(const StatHist &src) :
+ capacity_(src.capacity_), min_(src.min_), max_(src.max_),
+ scale_(src.scale_), val_in(src.val_in), val_out(src.val_out)
{
- for(int i=0;i<capacity;++i)
- bins[i]=0;
-}
-
-StatHist::~StatHist()
-{
- if (bins != NULL) {
- xfree(bins);
- bins = NULL;
+ if (src.bins!=NULL) {
+ bins = static_cast<bins_type *>(xcalloc(src.capacity_, sizeof(bins_type)));
+ memcpy(bins,src.bins,capacity_*sizeof(*bins));
}
}
-StatHist&
-StatHist::operator =(const StatHist & src)
-{
- assert(src.bins != NULL); // TODO: remove after initializing bins at construction time
- if (capacity != src.capacity) {
- // need to resize.
- xfree(bins);
- bins = static_cast<int *>(xcalloc(src.capacity, sizeof(int)));
- capacity=src.capacity;
-
- }
- min=src.min;
- max=src.max;
- scale=src.scale;
- val_in=src.val_in;
- val_out=src.val_out;
- memcpy(bins,src.bins,capacity*sizeof(*bins));
- return *this;
-}
-
void
-StatHist::count(double val)
+StatHist::count(double v)
{
- const int bin = findBin(val);
- assert(bins); /* make sure it got initialized */
- assert(0 <= bin && bin < capacity);
+ if (bins==NULL) //do not count before initialization or after destruction
+ return;
+ const unsigned int bin = findBin(v);
++bins[bin];
}
-int
+unsigned int
StatHist::findBin(double v)
{
- int bin;
- v -= min; /* offset */
+ v -= min_; /* offset */
- if (v <= 0.0) /* too small */
+ if (v <= 0.0) /* too small */
return 0;
- bin = (int) floor(scale * val_in(v) + 0.5);
+ unsigned int bin;
+ double tmp_bin=floor(scale_ * val_in(v) + 0.5);
- if (bin < 0) /* should not happen */
+ if (tmp_bin < 0.0) // should not happen
return 0;
+ bin = static_cast <unsigned int>(tmp_bin);
- if (bin >= capacity) /* too big */
- bin = capacity - 1;
+ if (bin >= capacity_) /* too big */
+ bin = capacity_ - 1;
return bin;
}
double
-StatHist::val(int bin) const
+StatHist::val(unsigned int bin) const
{
- return val_out((double) bin / scale) + min;
+ return val_out((double) bin / scale_) + min_;
}
double
double
StatHist::deltaPctile(const StatHist & B, double pctile) const
{
- int i;
- int s1 = 0;
- int h = 0;
- int a = 0;
- int b = 0;
- int I = 0;
- int J = capacity;
- int K;
+ unsigned int i;
+ bins_type s1 = 0;
+ bins_type h = 0;
+ bins_type a = 0;
+ bins_type b = 0;
+ unsigned int I = 0;
+ unsigned int J = capacity_;
+ unsigned int K;
double f;
- assert(capacity == B.capacity);
+ assert(capacity_ == B.capacity_);
- int *D = static_cast<int *>(xcalloc(capacity, sizeof(int)));
+ int *D = static_cast<int *>(xcalloc(capacity_, sizeof(int)));
- for (i = 0; i < capacity; ++i) {
+ for (i = 0; i < capacity_; ++i) {
D[i] = B.bins[i] - bins[i];
assert(D[i] >= 0);
}
- for (i = 0; i < capacity; ++i)
+ for (i = 0; i < capacity_; ++i)
s1 += D[i];
h = int(s1 * pctile);
- for (i = 0; i < capacity; ++i) {
+ for (i = 0; i < capacity_; ++i) {
J = i;
b += D[J];
f = (h - a) / (b - a);
- K = (int) floor(f * (double) (J - I) + I);
+ K = (unsigned int) floor(f * (double) (J - I) + I);
return val(K);
}
void
StatHist::dump(StoreEntry * sentry, StatHistBinDumper * bd) const
{
- int i;
- double left_border = min;
+ double left_border = min_;
if (!bd)
bd = statHistBinDumper;
- for (i = 0; i < capacity; ++i) {
+ for (unsigned int i = 0; i < capacity_; ++i) {
const double right_border = val(i + 1);
assert(right_border - left_border > 0.0);
bd(sentry, i, left_border, right_border - left_border, bins[i]);
}
}
+StatHist &
+StatHist::operator += (const StatHist &B)
+{
+ Must(capacity_ == B.capacity_);
+ Must(min_ == B.min_);
+ Must(max_ == B.max_);
+
+ if (B.bins == NULL) { // B was not yet initializted
+ return *this;
+ }
+ if (bins == NULL) { // this histogram was not yet initialized
+ *this = B;
+ return *this;
+ }
+ for (unsigned int i = 0; i < capacity_; ++i) {
+ bins[i] += B.bins[i];
+ }
+ return *this;
+}
+
/* log based histogram */
double
Math::Log(double x)
}
void
-StatHist::logInit(int capacity, double min, double max)
+StatHist::logInit(unsigned int capacity, double min, double max)
{
init(capacity, Math::Log, Math::Exp, min, max);
}
}
void
-StatHist::enumInit(int last_enum)
+StatHist::enumInit(unsigned int last_enum)
{
init(last_enum + 3, Math::Null, Math::Null, -1.0, (2.0 + last_enum));
}
void
-statHistEnumDumper(StoreEntry * sentry, int idx, double val, double size, int count)
+statHistEnumDumper(StoreEntry * sentry, int idx, double val, double, int count)
{
if (count)
storeAppendPrintf(sentry, "%2d\t %5d\t %5d\n",
}
void
-statHistIntDumper(StoreEntry * sentry, int idx, double val, double size, int count)
+statHistIntDumper(StoreEntry * sentry, int, double val, double, int count)
{
if (count)
storeAppendPrintf(sentry, "%9d\t%9d\n", (int) val, count);
}
+