send-announce.h \
send-announce.cc \
$(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ SBufDetailedStats.cc \
SBufStatsAction.h \
SBufStatsAction.cc \
$(SNMP_SOURCE) \
Packer.h \
SquidString.h \
SquidTime.h \
+ $(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
String.cc \
StrList.h \
StrList.cc \
StrList.cc \
tests/stub_StatHist.cc \
stmem.cc \
+ $(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
String.cc \
store_dir.cc \
StoreIOState.cc \
RemovalPolicy.cc \
Server.cc \
$(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
$(SNMP_SOURCE) \
SquidMath.h \
SquidMath.cc \
StatHist.h \
tests/stub_StatHist.cc \
stmem.cc \
+ $(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
StoreFileSystem.cc \
StoreIOState.cc \
tests/stub_StoreMeta.cc \
StrList.h \
StrList.cc \
$(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
$(SNMP_SOURCE) \
SquidMath.cc \
SquidMath.h \
refresh.cc \
Server.cc \
$(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
$(SNMP_SOURCE) \
SquidMath.h \
SquidMath.cc \
RemovalPolicy.cc \
Server.cc \
$(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
$(SNMP_SOURCE) \
SquidMath.h \
SquidMath.cc \
RemovalPolicy.cc \
Server.cc \
$(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
$(SNMP_SOURCE) \
SquidMath.h \
SquidMath.cc \
StoreSwapLogData.cc \
store_key_md5.h \
store_key_md5.cc \
+ $(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
String.cc \
StrList.h \
StrList.cc \
tests/stub_cache_cf.cc \
tests/stub_helper.cc \
cbdata.cc \
+ $(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
String.cc \
tests/stub_debug.cc \
tests/stub_client_side_request.cc \
store_key_md5.cc \
store_swapmeta.cc \
store_swapout.cc \
+ $(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
String.cc \
StrList.h \
StrList.cc \
RemovalPolicy.cc \
Server.cc \
$(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
$(SNMP_SOURCE) \
SquidMath.h \
SquidMath.cc \
tests/SBufFindTest.h \
tests/SBufFindTest.cc \
$(SBUF_SOURCE) \
+ SBufDetailedStats.h \
+ tests/stub_SBufDetailedStats.cc \
SBufStream.h \
tests/stub_time.cc \
mem.cc \
#include "Debug.h"
#include "Mem.h"
#include "MemBlob.h"
+#include "SBufDetailedStats.h"
#if HAVE_IOSTREAM
#include <iostream>
memFreeString(capacity,mem);
Stats.liveBytes -= capacity;
--Stats.live;
+ recordMemBlobSizeAtDestruct(size);
debugs(MEMBLOB_DEBUGSECTION,9, HERE << "destructed, this="
<< static_cast<void*>(this) << " id=" << id
#include "Debug.h"
#include "OutOfBoundsException.h"
#include "SBuf.h"
+#include "SBufDetailedStats.h"
#include "SBufExceptions.h"
#include "util.h"
{
debugs(24, 8, id << " destructed");
--stats.live;
+ recordSBufSizeAtDestruct(len_);
}
MemBlob::Pointer
--- /dev/null
+#include "squid.h"
+#include "SBufDetailedStats.h"
+#include "StatHist.h"
+
+/*
+ * Implementation note: the purpose of this construct is to avoid adding
+ * external dependencies to the SBuf code
+ */
+
+static StatHist sbufDestructTimeStats;
+static StatHist memblobDestructTimeStats;
+
+namespace SBufDetailedStatsHistInitializer {
+ // run the post-instantiation initialization methods for StatHist objects
+ struct Initializer
+ {
+ Initializer() {
+ sbufDestructTimeStats.logInit(300,30.0,128000.0);
+ memblobDestructTimeStats.logInit(300,30.0,128000.0);
+ }
+ };
+ Initializer initializer;
+}
+
+void
+recordSBufSizeAtDestruct(SBuf::size_type sz)
+{
+ sbufDestructTimeStats.count(static_cast<double>(sz));
+}
+
+const StatHist *
+collectSBufDestructTimeStats()
+{
+ return &sbufDestructTimeStats;
+}
+
+void
+recordMemBlobSizeAtDestruct(SBuf::size_type sz)
+{
+ memblobDestructTimeStats.count(static_cast<double>(sz));
+}
+
+const StatHist *
+collectMemBlobDestructTimeStats()
+{
+ return &memblobDestructTimeStats;
+}
--- /dev/null
+
+#ifndef SQUID_SBUFDETAILEDSTATS_H
+#define SQUID_SBUFDETAILEDSTATS_H
+
+#include "SBuf.h"
+
+class StatHist;
+
+/// Record the size a SBuf had when it was destructed
+void recordSBufSizeAtDestruct(SBuf::size_type sz);
+
+/** Collect the SBuf size-at-destruct-time histogram
+ *
+ * \note the returned StatHist object must not be freed
+ */
+const StatHist * collectSBufDestructTimeStats();
+
+/// Record the size a MemBlob had when it was destructed
+void recordMemBlobSizeAtDestruct(MemBlob::size_type sz);
+
+/** Collect the MemBlob size-at-destruct-time histogram
+ *
+ * \note the returned StatHist object must not be freed
+ */
+const StatHist * collectMemBlobDestructTimeStats();
+
+#endif /* SQUID_SBUFDETAILEDSTATS_H */
#include "ipc/Messages.h"
#include "ipc/TypedMsgHdr.h"
#include "mgr/Registration.h"
+#include "SBufDetailedStats.h"
#include "SBufStatsAction.h"
#include "StoreEntryStream.h"
{
sbdata += dynamic_cast<const SBufStatsAction&>(action).sbdata;
mbdata += dynamic_cast<const SBufStatsAction&>(action).mbdata;
+ sbsizesatdestruct += dynamic_cast<const SBufStatsAction&>(action).sbsizesatdestruct;
+ mbsizesatdestruct += dynamic_cast<const SBufStatsAction&>(action).mbsizesatdestruct;
}
void
{
sbdata = SBuf::GetStats();
mbdata = MemBlob::GetStats();
+ sbsizesatdestruct = *collectSBufDestructTimeStats();
+ mbsizesatdestruct = *collectMemBlobDestructTimeStats();
}
void
SBufStatsAction::dump(StoreEntry* entry)
{
StoreEntryStream ses(entry);
+ ses << "\n\n\nThese statistics are experimental; their format and contents "
+ "should not be relied upon, they are bound to change as "
+ "the SBuf feature is evolved\n";
sbdata.dump(ses);
mbdata.dump(ses);
- ses << "\n\n\nThese statistics are experimental; their format and contents "
- "should not be relied upon, they are bound to change as "
- "the SBuf feature is evolved";
+ ses << "\n";
+ ses << "SBuf size distribution at destruct time:\n";
+ sbsizesatdestruct.dump(entry,NULL);
+ ses << "MemBlob size distribution at destruct time:\n";
+ mbsizesatdestruct.dump(entry,NULL);
}
void
#include "mgr/Action.h"
#include "SBuf.h"
+#include "StatHist.h"
class StoreEntry;
SBufStats sbdata;
MemBlobStats mbdata;
+ StatHist sbsizesatdestruct;
+ StatHist mbsizesatdestruct;
};
#endif /* SQUID_SBUFSTATSACTION_H */
}
}
+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)
* this and the supplied histogram.
*/
double deltaPctile(const StatHist &B, double pctile) const;
+
/** obtain the output-transformed value from the specified bin
*
*/
double val(unsigned int bin) const;
+
/** increment the counter for the histogram entry
* associated to the supplied value
*/
void count(double val);
+
/** iterate the supplied bd function over the histogram values
*/
void dump(StoreEntry *sentry, StatHistBinDumper * bd) const;
+
/** Initialize the Histogram using a logarithmic values distribution
*/
void logInit(unsigned int capacity, double min, double max);
+
/** initialize the histogram to count occurrences in an enum-represented set
*/
void enumInit(unsigned int last_enum);
+
+ /** Import values from another histogram
+ *
+ * \note: the two histograms MUST have the same capicity, min and max or
+ * an exception will be raised
+ */
+ StatHist &operator += (const StatHist &B);
+
protected:
/** low-level initialize function. called by *Init high-level functions
* \note Important restrictions on val_in and val_out functions:
* See log and linear based histograms for examples
*/
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
unsigned int findBin(double v);
+
/// the histogram counters
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
double max_;
+
/// scaling factor when looking for a bin
double scale_;
hbase_f *val_in; /* e.g., log() for log-based histogram */
--- /dev/null
+#include "squid.h"
+#include "SBuf.h"
+
+#define STUB_API "SBufDetailedStats.cc"
+#include "tests/STUB.h"
+
+class StatHist;
+
+void recordSBufSizeAtDestruct(SBuf::size_type) STUB_NOP
+const StatHist * collectSBufDestructTimeStats() STUB_RETVAL(NULL)
+void recordMemBlobSizeAtDestruct(SBuf::size_type) STUB_NOP
+const StatHist * collectMemBlobDestructTimeStats() STUB_RETVAL(NULL)
CPPUNIT_ASSERT_EQUAL(static_cast<float>(123.5),f);
}
-void testSBuf::testCopy()
+void
+testSBuf::testCopy()
{
char buf[40]; //shorter than literal()
SBuf s(fox1),s2;
CPPUNIT_ASSERT_EQUAL(s2,s);
}
-void testSBuf::testStringOps()
+void
+testSBuf::testStringOps()
{
SBuf sng(literal.toLower()),
ref("the quick brown fox jumped over the lazy dog");
CPPUNIT_ASSERT_EQUAL(0,SBuf("the").compare(SBuf("THE"),caseInsensitive,6));
}
-void testSBuf::testGrow()
+void
+testSBuf::testGrow()
{
SBuf t;
t.assign("foo");
CPPUNIT_ASSERT_EQUAL(ref,match);
}
-void testSBuf::testStartsWith()
+void
+testSBuf::testStartsWith()
{
static SBuf casebuf("THE QUICK");
CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1)));
CPPUNIT_ASSERT_EQUAL(false,literal.startsWith(casebuf,caseInsensitive));
}
-void testSBuf::testSBufStream()
+void
+testSBuf::testSBufStream()
{
SBuf b("const.string, int 10 and a float 10.5");
SBufStream ss;
CPPUNIT_ASSERT_EQUAL(f1,SBuf(fox1));
}
-void testSBuf::testFindFirstOf()
+void
+testSBuf::testFindFirstOf()
{
SBuf haystack(literal);
SBuf::size_type idx;
CPPUNIT_ASSERT_EQUAL(4U,idx);
}
-void testSBuf::testAutoFind()
+void
+testSBuf::testAutoFind()
{
SBufFindTest test;
test.run();
}
-void testSBuf::testStdStringOps()
+void
+testSBuf::testStdStringOps()
{
const char *alphabet="abcdefghijklmnopqrstuvwxyz";
std::string astr(alphabet);
test.count(max);
//CPPUNIT_ASSERT(test.val(capacity-1)==1); //FIXME: val() returns a density
}
+
+void
+testStatHist::testStatHistSum()
+{
+ InspectingStatHist s1, s2;
+ s1.logInit(30,1.0,100.0);
+ s2.logInit(30,1.0,100.0);
+ s1.count(3);
+ s2.count(30);
+ InspectingStatHist ts1, ts2;
+ ts1=s1;
+ ts1+=s2;
+ ts2=s2;
+ ts2+=s1;
+ CPPUNIT_ASSERT(ts1 == ts2);
+ InspectingStatHist ts3;
+ ts3.logInit(30,1.0,100.0);
+ ts3.count(3);
+ ts3.count(30);
+ CPPUNIT_ASSERT(ts3 == ts1);
+
+}
CPPUNIT_TEST( testStatHistBaseEquality );
CPPUNIT_TEST( testStatHistBaseAssignment );
CPPUNIT_TEST( testStatHistLog );
+ CPPUNIT_TEST( testStatHistSum );
CPPUNIT_TEST_SUITE_END();
public:
void testStatHistBaseEquality();
void testStatHistBaseAssignment();
void testStatHistLog();
+ void testStatHistSum();
};
#endif /* TESTSTATHIST_H_ */