# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: kinkie@squid-cache.org-20111230134915-xrka2li1b2ui85wh
# target_branch: ../squid-trunk-co/
# testament_sha1: 17e44e7d00329587771effdb5910f33d0693ba8a
# timestamp: 2012-01-02 15:59:44 +0100
# source_branch: lp:~kinkie/squid/stathist
# base_revision_id: squid3@treenet.co.nz-20111230122914-\
#   e5bl2vg35ggm0d1o
# 
# Begin patch
=== modified file 'src/Makefile.am'
--- src/Makefile.am	2011-12-16 11:29:40 +0000
+++ src/Makefile.am	2011-12-28 15:54:04 +0000
@@ -1115,27 +1115,7 @@
 	$(XTRA_LIBS)
 tests_testHttpReply_DEPENDENCIES= $(SQUID_CPPUNIT_LA)
 
-## Tests for the ACLMaxUserIP class
-## acl needs wordlist. wordlist needs MemBug
-## MemBuf needs mem, MemBuf needs event,
-## event needs cbdata.
-## ACLMaxUserUP needs $(AUTH_LIBS)
-## ACLMaxUserIP needs ACLChecklist
-## AuthUser request needs HttpHeader, which brings in 
-##	ETag.cc \
-##	HttpHeader.cc \
-##	HttpHeaderTools.cc \
-##	HttpHdrContRange.cc \
-##	HttpHdrCc.cc \
-##	HttpHdrRange.cc \
-##	HttpHdrSc.cc \
-##	HttpHdrScTarget.cc \
-##	Packer.cc \
-##	StatHist.cc \
-##	String.cc \
-##
-##	disk.cc \
-##	fs/libfs.la \
+
 tests_testACLMaxUserIP_SOURCES= \
 	cbdata.cc \
 	ClientInfo.h \
@@ -1168,7 +1148,7 @@
 	SquidMath.cc \
 	StatCounters.h \
 	StatHist.h \
-	StatHist.cc \
+	tests/stub_StatHist.cc \
 	stmem.cc \
 	String.cc \
 	store_dir.cc \
@@ -1370,7 +1350,7 @@
 	StatCounters.h \
 	StatCounters.cc \
 	StatHist.h \
-	StatHist.cc \
+	tests/stub_StatHist.cc \
 	stmem.cc \
 	store.cc \
 	store_client.cc \
@@ -1496,7 +1476,7 @@
 	StatCounters.h \
 	StatCounters.cc \
 	StatHist.h \
-	StatHist.cc \
+	tests/stub_StatHist.cc \
 	stmem.cc \
 	StoreFileSystem.cc \
 	StoreIOState.cc \
@@ -2765,7 +2745,7 @@
 	StatCounters.h \
 	StatCounters.cc \
 	StatHist.h \
-	StatHist.cc \
+	tests/stub_StatHist.cc \
 	stmem.cc \
 	store.cc \
 	StoreFileSystem.cc \
@@ -2936,9 +2916,7 @@
 	StatCounters.h \
 	StatCounters.cc \
 	StatHist.h \
-	StatHist.cc \
-	HttpHdrRange.cc \
-	ETag.cc \
+	tests/stub_StatHist.cc \
 	tests/stub_errorpage.cc \
 	tests/stub_HttpRequest.cc \
 	tests/stub_access_log.cc \
@@ -3074,9 +3052,7 @@
 	StatCounters.h \
 	StatCounters.cc \
 	StatHist.h \
-	StatHist.cc \
-	HttpHdrRange.cc \
-	ETag.cc \
+	tests/stub_StatHist.cc \
 	tests/stub_errorpage.cc \
 	tests/stub_HttpRequest.cc \
 	tests/stub_access_log.cc \
@@ -3228,7 +3204,7 @@
 	StatCounters.h \
 	StatCounters.cc \
 	StatHist.h \
-	StatHist.cc \
+	tests/stub_StatHist.cc \
 	stmem.cc \
 	store.cc \
 	store_client.cc \

=== modified file 'src/StatHist.cc'
--- src/StatHist.cc	2011-12-18 01:31:58 +0000
+++ src/StatHist.cc	2011-12-28 10:42:27 +0000
@@ -46,9 +46,8 @@
 
 /* low level init, higher level functions has less params */
 void
-StatHist::init(int newCapacity, hbase_f * val_in_, hbase_f * val_out_, double newMin, double newMax)
+StatHist::init(unsigned int newCapacity, hbase_f * val_in_, hbase_f * val_out_, double newMin, double newMax)
 {
-    assert(newCapacity > 0);
     assert(val_in_ && val_out_);
     /* check before we divide to get scale_ */
     assert(val_in_(newMax - newMin) > 0);
@@ -57,22 +56,22 @@
     capacity_ = newCapacity;
     val_in = val_in_;
     val_out = val_out_;
-    bins = static_cast<int *>(xcalloc(capacity_, sizeof(int)));
+    bins = static_cast<bins_type *>(xcalloc(capacity_, sizeof(bins_type)));
     scale_ = capacity_ / val_in(max_ - min_);
 
     /* check that functions are valid */
     /* a min value should go into bin[0] */
-    assert(findBin(min_) == 0);
+    assert(findBin(min_) == 0);  //TODO: move to unit test
     /* a max value should go into the last bin */
-    assert(findBin(max_) == capacity_ - 1);
+    assert(findBin(max_) == capacity_ - 1);  //TODO: move to unit test
     /* it is hard to test val_out, here is a crude test */
-    assert(((int) floor(0.99 + val(0) - min_)) == 0);
+    assert(((int) floor(0.99 + val(0) - min_)) == 0);  //TODO: move to unit test
 }
 
 void
 StatHist::clear()
 {
-    for (int i=0; i<capacity_; ++i)
+    for (unsigned int i=0; i<capacity_; ++i)
         bins[i]=0;
 }
 
@@ -84,6 +83,7 @@
     }
 }
 
+// any changes must be copied to stub_StatHist
 StatHist&
 StatHist::operator =(const StatHist & src)
 {
@@ -93,7 +93,7 @@
     if (capacity_ != src.capacity_) {
         // need to resize.
         xfree(bins);
-        bins = static_cast<int *>(xcalloc(src.capacity_, sizeof(int)));
+        bins = static_cast<bins_type *>(xcalloc(src.capacity_, sizeof(bins_type)));
         capacity_=src.capacity_;
 
     }
@@ -111,7 +111,7 @@
         scale_(src.scale_), val_in(src.val_in), val_out(src.val_out)
 {
     if (src.bins!=NULL) {
-        bins = static_cast<int *>(xcalloc(src.capacity_, sizeof(int)));
+        bins = static_cast<bins_type *>(xcalloc(src.capacity_, sizeof(int)));
         memcpy(bins,src.bins,capacity_*sizeof(*bins));
     }
 }
@@ -119,26 +119,27 @@
 void
 StatHist::count(double val)
 {
-    const int bin = findBin(val);
+    const unsigned int bin = findBin(val);
     assert(bins);		/* make sure it got initialized */
-    assert(0 <= bin && bin < capacity_);
+    assert(bin < capacity_);
     ++bins[bin];
 }
 
-int
+unsigned int
 StatHist::findBin(double v)
 {
-    int bin;
 
     v -= min_;		/* offset */
 
     if (v <= 0.0)		/* too small */
         return 0;
 
-    bin = (int) floor(scale_ * val_in(v) + 0.5);
+    unsigned int bin;
+    float 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;
@@ -147,7 +148,7 @@
 }
 
 double
-StatHist::val(int bin) const
+StatHist::val(unsigned int bin) const
 {
     return val_out((double) bin / scale_) + min_;
 }
@@ -167,14 +168,14 @@
 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_);
@@ -219,7 +220,7 @@
 
     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);
 }
@@ -235,13 +236,12 @@
 void
 StatHist::dump(StoreEntry * sentry, StatHistBinDumper * bd) const
 {
-    int i;
     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]);
@@ -264,7 +264,7 @@
 }
 
 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);
 }
@@ -278,7 +278,7 @@
 }
 
 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));
 }

=== modified file 'src/StatHist.h'
--- src/StatHist.h	2011-12-17 21:23:14 +0000
+++ src/StatHist.h	2011-12-27 16:05:54 +0000
@@ -59,6 +59,8 @@
     StatHist(const StatHist&); //not needed
     ~StatHist();
 
+    typedef uint64_t bins_type;
+
     StatHist &operator=(const StatHist &);
     /** clear the contents of the histograms
      *
@@ -74,7 +76,7 @@
     /** obtain the output-transformed value from the specified bin
      *
      */
-    double val(int bin) const;
+    double val(unsigned int bin) const;
     /** increment the counter for the histogram entry
      * associated to the supplied value
      */
@@ -84,10 +86,10 @@
     void dump(StoreEntry *sentry, StatHistBinDumper * bd) const;
     /** Initialize the Histogram using a logarithmic values distribution
      */
-    void logInit(int capacity, double min, double max);
+    void logInit(unsigned int capacity, double min, double max);
     /** initialize the histogram to count occurrences in an enum-represented set
      */
-    void enumInit(int last_enum);
+    void enumInit(unsigned int last_enum);
 protected:
     /** low-level initialize function. called by *Init high-level functions
      * \note Important restrictions on val_in and val_out functions:
@@ -100,13 +102,13 @@
      *  val_in is applied after offseting the value but before scaling
      *  See log and linear based histograms for examples
      */
-    void init(int capacity, hbase_f * val_in, hbase_f * val_out, double min, double max);
+    void init(unsigned int capacity, hbase_f * val_in, hbase_f * val_out, double min, double max);
     /// find what entry in the histogram corresponds to v, by applying
     /// the preset input transformation function
-    int findBin(double v);
+    unsigned int findBin(double v);
     /// the histogram counters
-    int *bins;
-    int capacity_;
+    bins_type *bins;
+    unsigned int capacity_;
     /// minimum value to be stored, corresponding to the first bin
     double min_;
     /// value of the maximum counter in the histogram

=== modified file 'src/tests/stub_StatHist.cc'
--- src/tests/stub_StatHist.cc	2011-12-15 07:01:07 +0000
+++ src/tests/stub_StatHist.cc	2011-12-28 15:54:04 +0000
@@ -1,24 +1,64 @@
 #include "config.h"
+#define STUB_API "StatHist.cc"
 #include "STUB.h"
 #include "StatHist.h"
 
-#define STUB_API "StatHist.cc"
-
-void
-StatHist::init(int capacity_, hbase_f * val_in_, hbase_f * val_out_, double min_, double max_)
-{}
 
 StatHist::~StatHist()
 {}
 
 void
-StatHist::enumInit(int last_enum)
-{}
-
-void
-StatHist::count(double val)
-{}
-
-void
 StatHist::dump(StoreEntry * sentry, StatHistBinDumper * bd) const
 {}
+
+void
+StatHist::enumInit(unsigned int i)
+{}
+
+void
+StatHist::count(double d)
+{}
+
+double
+statHistDeltaMedian(const StatHist & A, const StatHist & B)
+STUB_RETVAL(0.0)
+
+double
+statHistDeltaPctile(const StatHist & A, const StatHist & B, double pctile)
+STUB_RETVAL(0.0)
+
+void
+StatHist::clear()
+STUB
+
+void
+StatHist::logInit(unsigned int i, double d1, double d2)
+STUB
+
+//verbatim copy from StatHist.cc
+StatHist&
+StatHist::operator =(const StatHist & src)
+{
+    if (this==&src) //handle self-assignment
+        return *this;
+    assert(src.bins != NULL); // TODO: remove after initializing bins at construction time
+    if (capacity_ != src.capacity_) {
+        // need to resize.
+        xfree(bins);
+        bins = static_cast<bins_type *>(xcalloc(src.capacity_, sizeof(bins_type)));
+        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;
+}
+
+class StoreEntry;
+void
+statHistIntDumper(StoreEntry * sentry, int idx, double val, double size, int count)
+STUB

=== added file 'src/tests/testStatHist.cc'
--- src/tests/testStatHist.cc	1970-01-01 00:00:00 +0000
+++ src/tests/testStatHist.cc	2011-12-27 16:05:54 +0000
@@ -0,0 +1,56 @@
+#define SQUID_UNIT_TEST 1
+#include "config.h"
+#include "testStatHist.h"
+#include "StatHist.h"
+
+typedef enum {
+    ZERO, ONE, TWO, THREE, FOUR, FIVE
+} number ;
+
+void
+testStatHist::testStatHistBaseEquality()
+{
+    StatHistEnum raw(FIVE), test(FIVE);
+    CPPUNIT_ASSERT(raw==test);
+    test.count(ZERO);
+    CPPUNIT_ASSERT_ASSERTION_FAIL(CPPUNIT_ASSERT(raw==test));
+}
+
+void
+testStatHist::testStatHistBaseAssignment()
+{
+    StatHistEnum raw(FIVE), test(FIVE);
+    test.count(ZERO);
+    test=raw;
+    CPPUNIT_ASSERT(raw==test);
+}
+
+void
+testStatHist::testStatHistBase()
+{
+    StatHistEnum raw(FIVE), test(FIVE);
+    // test equality test
+    CPPUNIT_ASSERT(raw==test);
+    test.count(ZERO);
+    test=raw;
+    CPPUNIT_ASSERT(raw==test);
+}
+
+void
+testStatHist::testStatHistEnum()
+{
+}
+
+void
+testStatHist::testStatHistLog()
+{
+    const double min=0.0, max=10000.0;
+    const int capacity=10;
+    StatHistLog raw(capacity,min,max), test=raw;
+    test.count(min);
+    CPPUNIT_ASSERT(test.val(0)==1);
+    CPPUNIT_ASSERT(test.val(1)==0);
+    test=raw;
+    test.count(max);
+    CPPUNIT_ASSERT(test.val(capacity-1)==1);
+}

=== added file 'src/tests/testStatHist.h'
--- src/tests/testStatHist.h	1970-01-01 00:00:00 +0000
+++ src/tests/testStatHist.h	2011-12-27 16:05:54 +0000
@@ -0,0 +1,30 @@
+/*
+ * StatHist unit test
+ */
+
+#ifndef TESTSTATHIST_H_
+#define TESTSTATHIST_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+
+class testStatHist : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE( testStatHist );
+    CPPUNIT_TEST( testStatHistBaseEquality );
+    CPPUNIT_TEST( testStatHistBase );
+    CPPUNIT_TEST( testStatHistEnum );
+    CPPUNIT_TEST( testStatHistLog );
+    CPPUNIT_TEST_SUITE_END();
+
+    public:
+
+    protected:
+    void testStatHistBaseEquality();
+    void testStatHistBaseAssignment();
+    void testStatHistBase();
+    void testStatHistEnum();
+    void testStatHistLog();
+};
+
+#endif /* TESTSTATHIST_H_ */