]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Merge from StatHist refactor.
authorFrancesco Chemolli <kinkie@squid-cache.org>
Thu, 19 Jan 2012 20:08:53 +0000 (21:08 +0100)
committerFrancesco Chemolli <kinkie@squid-cache.org>
Thu, 19 Jan 2012 20:08:53 +0000 (21:08 +0100)
Added StatHist unit tests, and moved algorithm consistency checks there.
Expanded storage for histograms to 64bit unsigned.
Inlined StatHist constructor, destructor and assignment operator.
Implemented stubs for StatHist.cc and mem.cc

src/Makefile.am
src/StatHist.cc
src/StatHist.h
src/tests/stub_StatHist.cc
src/tests/stub_mem.cc [new file with mode: 0644]
src/tests/stub_stmem.cc
src/tests/testStatHist.cc [new file with mode: 0644]
src/tests/testStatHist.h [new file with mode: 0644]

index 0a2b397eb2298dd1cd3759e73ecb7acc10806bc5..fda261dec96d8249092de65916af732393ab5610 100644 (file)
@@ -1015,6 +1015,7 @@ check_PROGRAMS+=\
        tests/testString \
        tests/testURL \
        tests/testConfigParser \
+       tests/testStatHist \
        $(STORE_TESTS)
 
 ## NP: required to run the above list. check_PROGRAMS only builds the binaries...
@@ -1115,27 +1116,7 @@ tests_testHttpReply_LDADD=\
        $(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 +1149,7 @@ tests_testACLMaxUserIP_SOURCES= \
        SquidMath.cc \
        StatCounters.h \
        StatHist.h \
-       StatHist.cc \
+       tests/stub_StatHist.cc \
        stmem.cc \
        String.cc \
        store_dir.cc \
@@ -1370,7 +1351,7 @@ tests_testCacheManager_SOURCES = \
        StatCounters.h \
        StatCounters.cc \
        StatHist.h \
-       StatHist.cc \
+       tests/stub_StatHist.cc \
        stmem.cc \
        store.cc \
        store_client.cc \
@@ -1496,7 +1477,7 @@ tests_testDiskIO_SOURCES = \
        StatCounters.h \
        StatCounters.cc \
        StatHist.h \
-       StatHist.cc \
+       tests/stub_StatHist.cc \
        stmem.cc \
        StoreFileSystem.cc \
        StoreIOState.cc \
@@ -2767,7 +2748,7 @@ tests_testRock_SOURCES = \
        StatCounters.h \
        StatCounters.cc \
        StatHist.h \
-       StatHist.cc \
+       tests/stub_StatHist.cc \
        stmem.cc \
        store.cc \
        StoreFileSystem.cc \
@@ -2937,9 +2918,7 @@ tests_testCoss_SOURCES = \
        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 \
@@ -3075,9 +3054,7 @@ tests_testNull_SOURCES = \
        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 \
@@ -3229,7 +3206,7 @@ tests_testURL_SOURCES = \
        StatCounters.h \
        StatCounters.cc \
        StatHist.h \
-       StatHist.cc \
+       tests/stub_StatHist.cc \
        stmem.cc \
        store.cc \
        store_client.cc \
@@ -3350,6 +3327,41 @@ tests_testConfigParser_LDADD = \
 tests_testConfigParser_LDFLAGS = $(LIBADD_DL)
 tests_testConfigParser_DEPENDENCIES = \
        $(SQUID_CPPUNIT_LA)
+       
+tests_testStatHist_SOURCES = \
+       cbdata.cc \
+       MemBuf.cc \
+       StatHist.cc \
+       StatHist.h \
+       String.cc \
+       tests/stub_cache_manager.cc \
+       tests/stub_comm.cc \
+       tests/stub_debug.cc \
+       tests/stub_DelayId.cc \
+       tests/stub_HelperChildConfig.cc \
+       tests/stub_mem.cc \
+       tests/stub_MemObject.cc \
+       tests/stub_mime.cc \
+       tests/stub_pconn.cc \
+       tests/stub_stmem.cc \
+       tests/stub_store.cc \
+       tests/stub_store_stats.cc \
+       tests/stub_tools.cc \
+       tests/testMain.cc \
+       tests/testStatHist.cc \
+       tests/testStatHist.h \
+       time.cc
+nodist_tests_testStatHist_SOURCES = \
+       $(TESTSOURCES)
+tests_testStatHist_LDFLAGS = $(LIBADD_DL)
+tests_testStatHist_LDADD = \
+       base/libbase.la \
+       $(top_builddir)/lib/libmiscutil.la \
+       $(SQUID_CPPUNIT_LIBS) \
+       $(SQUID_CPPUNIT_LA) \
+       $(COMPAT_LIB)
+tests_testStatHist_DEPENDENCIES = $(SQUID_CPPUNIT_LA)
+
 
 TESTS += testHeaders
 
index 71e651ee3b26e2074e60b62763a2d6683b278c57..f760577aed5118270029fc2f2d39868c1fcb704b 100644 (file)
@@ -46,10 +46,8 @@ hbase_f Null;
 
 /* 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);
     min_ = newMin;
@@ -57,61 +55,23 @@ StatHist::init(int newCapacity, hbase_f * val_in_, hbase_f * val_out_, double ne
     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);
-    /* 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);
 }
 
 void
 StatHist::clear()
 {
-    for (int i=0; i<capacity_; ++i)
+    for (unsigned int i=0; i<capacity_; ++i)
         bins[i]=0;
 }
 
-StatHist::~StatHist()
-{
-    if (bins != NULL) {
-        xfree(bins);
-        bins = NULL;
-    }
-}
-
-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<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;
-}
-
 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)
 {
     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 +79,27 @@ StatHist::StatHist(const StatHist &src) :
 void
 StatHist::count(double val)
 {
-    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(val);
     ++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;
+    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;
@@ -147,7 +108,7 @@ StatHist::findBin(double v)
 }
 
 double
-StatHist::val(int bin) const
+StatHist::val(unsigned int bin) const
 {
     return val_out((double) bin / scale_) + min_;
 }
@@ -167,14 +128,14 @@ statHistDeltaPctile(const StatHist & A, const StatHist & B, double pctile)
 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 +180,7 @@ StatHist::deltaPctile(const StatHist & B, double pctile) const
 
     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 +196,12 @@ statHistBinDumper(StoreEntry * sentry, int idx, double val, double size, int cou
 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 +224,7 @@ Math::Exp(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);
 }
@@ -278,7 +238,7 @@ Math::Null(double x)
 }
 
 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));
 }
index dcd4e687140a3572c2c5a8d882f6bffb19da6e2a..576525d21a16d348cc085e9a8fbbc914e4d30dbd 100644 (file)
@@ -55,11 +55,14 @@ public:
      * \todo specialize the class in a small hierarchy so that all
      *       relevant initializations are done at build-time
      */
-    StatHist() : scale_(1.0) {}
+    StatHist();
     StatHist(const StatHist&); //not needed
     ~StatHist();
 
+    typedef uint64_t bins_type;
+
     StatHist &operator=(const StatHist &);
+
     /** clear the contents of the histograms
      *
      * \todo remove: this function has been replaced in its purpose
@@ -74,7 +77,7 @@ public:
     /** 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 +87,10 @@ public:
     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 +103,13 @@ protected:
      *  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
@@ -122,4 +125,35 @@ double statHistDeltaPctile(const StatHist & A, const StatHist & B, double pctile
 StatHistBinDumper statHistEnumDumper;
 StatHistBinDumper statHistIntDumper;
 
+inline StatHist&
+StatHist::operator =(const StatHist & src)
+{
+    if (this==&src) //handle self-assignment
+        return *this;
+    xfree(bins); // xfree can handle NULL pointers, no need to check
+    capacity_=src.capacity_;
+    bins = static_cast<bins_type *>(xcalloc(src.capacity_, sizeof(bins_type)));
+    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;
+}
+
+inline
+StatHist::StatHist() :
+        bins(NULL), capacity_(0), min_(0), max_(0),
+        scale_(1.0), val_in(NULL), val_out(NULL)
+{}
+
+inline
+StatHist::~StatHist()
+{
+    xfree(bins); //can handle case of bins being NULL
+    bins=NULL;
+    capacity_=0; //mark as destructed, may be needed for troubleshooting
+}
+
 #endif /* STATHIST_H_ */
index b75787cb254fd72acbf66a2d410329e13de0f8ed..dd48a0bcfbe589cbdb40392e312a8b66e0600e42 100644 (file)
@@ -1,24 +1,39 @@
 #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::dump(StoreEntry * sentry, StatHistBinDumper * bd) const
 {}
 
-StatHist::~StatHist()
+void
+StatHist::enumInit(unsigned int i)
 {}
 
 void
-StatHist::enumInit(int last_enum)
+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::count(double val)
-{}
+StatHist::clear()
+STUB
 
 void
-StatHist::dump(StoreEntry * sentry, StatHistBinDumper * bd) const
-{}
+StatHist::logInit(unsigned int i, double d1, double d2)
+STUB
+
+class StoreEntry;
+void
+statHistIntDumper(StoreEntry * sentry, int idx, double val, double size, int count)
+STUB
+
diff --git a/src/tests/stub_mem.cc b/src/tests/stub_mem.cc
new file mode 100644 (file)
index 0000000..49b5a78
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * stub file for mem.cc
+ */
+
+#include "config.h"
+
+#define STUB_API "stub_mem.cc"
+#include "STUB.h"
+/* mem* definitions are still in protos.h */
+#include "protos.h"
+
+extern "C" void
+memFreeString(size_t size, void *buf)
+{
+    xfree(buf);
+}
+
+extern "C" void *
+memAllocString(size_t net_size, size_t * gross_size)
+{
+    *gross_size=net_size;
+    return xmalloc(net_size);
+}
+
+extern "C" void
+memFreeBuf(size_t size, void *buf)
+{
+    xfree(buf);
+}
+
+extern "C" void *
+memAllocBuf(size_t net_size, size_t * gross_size)
+{
+    *gross_size=net_size;
+    return xcalloc(1, net_size);
+}
+
+/* net_size is the new size, *gross size is the old gross size, to be changed to
+ * the new gross size as a side-effect.
+ */
+extern "C" void *
+memReallocBuf(void *oldbuf, size_t net_size, size_t * gross_size)
+{
+    void *rv=xrealloc(oldbuf,net_size);
+//    if (net_size > *gross_size)
+//        memset(rv+net_size,0,net_size-*gross_size);
+    *gross_size=net_size;
+    return rv;
+}
+
+static void
+cxx_xfree(void * ptr)
+{
+           xfree(ptr);
+}
+
+FREE *
+memFreeBufFunc(size_t size)
+{
+    return cxx_xfree;
+}
+
+void *
+memAllocate(mem_type type)
+STUB_RETVAL(NULL)
+
+void
+memFree(void *p, int type)
+STUB
index 4ddf12f1622430639f350441ade4a46f3e3dc80d..cee7152423ba5708f02476032e51b1ed943a1faf 100644 (file)
@@ -7,3 +7,6 @@
 mem_hdr::mem_hdr() STUB
 mem_hdr::~mem_hdr() STUB
 size_t mem_hdr::size() const STUB_RETVAL(0)
+int64_t mem_hdr::endOffset () const STUB_RETVAL(0)
+bool mem_hdr::write (StoreIOBuffer const &writeBuffer) STUB_RETVAL(false)
+
diff --git a/src/tests/testStatHist.cc b/src/tests/testStatHist.cc
new file mode 100644 (file)
index 0000000..065907b
--- /dev/null
@@ -0,0 +1,78 @@
+#define SQUID_UNIT_TEST 1
+#include "config.h"
+#include "testStatHist.h"
+#include "StatHist.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(testStatHist);
+
+typedef enum {
+    ZERO, ONE, TWO, THREE, FOUR, FIVE
+} number ;
+
+class InspectingStatHist : public StatHist
+{
+public:
+    bool operator==(const InspectingStatHist &);
+    bins_type counter(double val) {
+        return bins[findBin(val)];
+    }
+};
+
+bool
+InspectingStatHist::operator ==(const InspectingStatHist & src)
+{
+    assert(bins != NULL && src.bins != NULL); // TODO: remove after initializing bins at construction time
+    if (capacity_ != src.capacity_ ||
+                    min_!=src.min_ ||
+                    max_!=src.max_ ||
+                    scale_!=src.scale_ ||
+                    val_in!=src.val_in ||
+                    val_out!=src.val_out)
+        return false;
+    return (memcmp(bins,src.bins,capacity_*sizeof(*bins))==0);
+}
+
+
+
+void
+testStatHist::testStatHistBaseEquality()
+{
+    InspectingStatHist raw, test;
+    raw.enumInit(FIVE);
+    test.enumInit(FIVE);
+    CPPUNIT_ASSERT(raw==test);
+    test.count(ZERO);
+    CPPUNIT_ASSERT_ASSERTION_FAIL(CPPUNIT_ASSERT(raw==test));
+}
+
+void
+testStatHist::testStatHistBaseAssignment()
+{
+    InspectingStatHist raw, test;
+    raw.enumInit(FIVE);
+    test.enumInit(FIVE);
+    test.count(ZERO);
+    CPPUNIT_ASSERT_ASSERTION_FAIL(CPPUNIT_ASSERT(raw==test));
+    test=raw;
+    CPPUNIT_ASSERT(raw==test);
+}
+
+
+void
+testStatHist::testStatHistLog()
+{
+    const double min=0.0, max=10000.0;
+    const int capacity=10;
+    InspectingStatHist raw, test;
+    raw.logInit(capacity,min,max);
+    test=raw;
+    CPPUNIT_ASSERT(test.counter(min)==0);
+    test.count(min);
+    CPPUNIT_ASSERT(test.counter(min)==1);
+    CPPUNIT_ASSERT(test.counter(max)==0);
+    test.count(max);
+    CPPUNIT_ASSERT(test.counter(max)==1);
+    test=raw;
+    test.count(max);
+    //CPPUNIT_ASSERT(test.val(capacity-1)==1); //FIXME: val() returns a density
+}
diff --git a/src/tests/testStatHist.h b/src/tests/testStatHist.h
new file mode 100644 (file)
index 0000000..2037fb0
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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( testStatHistBaseAssignment );
+    CPPUNIT_TEST( testStatHistLog );
+    CPPUNIT_TEST_SUITE_END();
+
+    public:
+
+    protected:
+    void testStatHistBaseEquality();
+    void testStatHistBaseAssignment();
+    void testStatHistLog();
+};
+
+#endif /* TESTSTATHIST_H_ */