Hi, the attached patch records (and displays in cachemgr) the histogram of the sizes of SBufs and MemBlobs.
Builds and runs, but since SBuf is not yet used, no meaningful output can be obtained. The code lives as lp:~squid/squid/stringng (together with other not yet merged SBuf bits, this is a cherrypick). -- /kinkie
=== modified file 'src/Makefile.am' --- src/Makefile.am 2013-11-22 09:31:30 +0000 +++ src/Makefile.am 2013-11-22 22:02:11 +0000 @@ -486,6 +486,8 @@ send-announce.h \ send-announce.cc \ $(SBUF_SOURCE) \ + SBufDetailedStats.h \ + SBufDetailedStats.cc \ SBufStatsAction.h \ SBufStatsAction.cc \ $(SNMP_SOURCE) \ @@ -1514,6 +1516,8 @@ RemovalPolicy.cc \ Server.cc \ $(SBUF_SOURCE) \ + SBufDetailedStats.h \ + tests/stub_SBufDetailedStats.cc \ $(SNMP_SOURCE) \ SquidMath.h \ SquidMath.cc \ @@ -1928,6 +1932,8 @@ StrList.h \ StrList.cc \ $(SBUF_SOURCE) \ + SBufDetailedStats.h \ + tests/stub_SBufDetailedStats.cc \ $(SNMP_SOURCE) \ SquidMath.cc \ SquidMath.h \ @@ -2170,6 +2176,8 @@ refresh.cc \ Server.cc \ $(SBUF_SOURCE) \ + SBufDetailedStats.h \ + tests/stub_SBufDetailedStats.cc \ $(SNMP_SOURCE) \ SquidMath.h \ SquidMath.cc \ @@ -2409,6 +2417,8 @@ RemovalPolicy.cc \ Server.cc \ $(SBUF_SOURCE) \ + SBufDetailedStats.h \ + tests/stub_SBufDetailedStats.cc \ $(SNMP_SOURCE) \ SquidMath.h \ SquidMath.cc \ @@ -2694,6 +2704,8 @@ RemovalPolicy.cc \ Server.cc \ $(SBUF_SOURCE) \ + SBufDetailedStats.h \ + tests/stub_SBufDetailedStats.cc \ $(SNMP_SOURCE) \ SquidMath.h \ SquidMath.cc \ @@ -3487,6 +3499,8 @@ RemovalPolicy.cc \ Server.cc \ $(SBUF_SOURCE) \ + SBufDetailedStats.h \ + tests/stub_SBufDetailedStats.cc \ $(SNMP_SOURCE) \ SquidMath.h \ SquidMath.cc \ @@ -3602,6 +3616,8 @@ tests/SBufFindTest.h \ tests/SBufFindTest.cc \ $(SBUF_SOURCE) \ + SBufDetailedStats.h \ + tests/stub_SBufDetailedStats.cc \ SBufStream.h \ tests/stub_time.cc \ mem.cc \ === modified file 'src/MemBlob.cc' --- src/MemBlob.cc 2013-10-04 15:33:54 +0000 +++ src/MemBlob.cc 2013-11-22 21:51:09 +0000 @@ -31,6 +31,7 @@ #include "Debug.h" #include "Mem.h" #include "MemBlob.h" +#include "SBufDetailedStats.h" #if HAVE_IOSTREAM #include <iostream> @@ -96,6 +97,7 @@ memFreeString(capacity,mem); Stats.liveBytes -= capacity; --Stats.live; + recordMemBlobSizeAtDestruct(size); debugs(MEMBLOB_DEBUGSECTION,9, HERE << "destructed, this=" << static_cast<void*>(this) << " id=" << id === modified file 'src/SBuf.cc' --- src/SBuf.cc 2013-10-07 11:23:58 +0000 +++ src/SBuf.cc 2013-11-22 21:50:30 +0000 @@ -31,6 +31,7 @@ #include "Debug.h" #include "OutOfBoundsException.h" #include "SBuf.h" +#include "SBufDetailedStats.h" #include "SBufExceptions.h" #include "util.h" @@ -148,6 +149,7 @@ { debugs(24, 8, id << " destructed"); --stats.live; + recordSBufSizeAtDestruct(len_); } MemBlob::Pointer === added file 'src/SBufDetailedStats.cc' --- src/SBufDetailedStats.cc 1970-01-01 00:00:00 +0000 +++ src/SBufDetailedStats.cc 2013-11-23 16:53:40 +0000 @@ -0,0 +1,47 @@ +#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 { + // 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; +} === added file 'src/SBufDetailedStats.h' --- src/SBufDetailedStats.h 1970-01-01 00:00:00 +0000 +++ src/SBufDetailedStats.h 2013-11-23 16:33:58 +0000 @@ -0,0 +1,18 @@ +#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(); === modified file 'src/SBufStatsAction.cc' --- src/SBufStatsAction.cc 2013-10-10 08:44:03 +0000 +++ src/SBufStatsAction.cc 2013-11-23 12:02:59 +0000 @@ -30,6 +30,7 @@ #include "ipc/Messages.h" #include "ipc/TypedMsgHdr.h" #include "mgr/Registration.h" +#include "SBufDetailedStats.h" #include "SBufStatsAction.h" #include "StoreEntryStream.h" @@ -48,6 +49,8 @@ { 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 @@ -55,6 +58,8 @@ { sbdata = SBuf::GetStats(); mbdata = MemBlob::GetStats(); + sbsizesatdestruct = *collectSBufDestructTimeStats(); + mbsizesatdestruct = *collectMemBlobDestructTimeStats(); } void @@ -63,9 +68,14 @@ StoreEntryStream ses(entry); sbdata.dump(ses); mbdata.dump(ses); + 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); 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"; + "the SBuf feature is evolved\n"; } void === modified file 'src/SBufStatsAction.h' --- src/SBufStatsAction.h 2013-10-10 08:44:03 +0000 +++ src/SBufStatsAction.h 2013-11-23 12:02:23 +0000 @@ -31,6 +31,7 @@ #include "mgr/Action.h" #include "SBuf.h" +#include "StatHist.h" class StoreEntry; @@ -55,6 +56,8 @@ SBufStats sbdata; MemBlobStats mbdata; + StatHist sbsizesatdestruct; + StatHist mbsizesatdestruct; }; #endif /* SQUID_SBUFSTATSACTION_H */ === modified file 'src/StatHist.cc' --- src/StatHist.cc 2013-01-21 07:15:09 +0000 +++ src/StatHist.cc 2013-11-23 11:23:44 +0000 @@ -205,6 +205,26 @@ } } +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) === modified file 'src/StatHist.h' --- src/StatHist.h 2012-08-28 13:00:30 +0000 +++ src/StatHist.h 2013-11-23 11:04:03 +0000 @@ -90,6 +90,12 @@ /** 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: === added file 'src/tests/stub_SBufDetailedStats.cc' --- src/tests/stub_SBufDetailedStats.cc 1970-01-01 00:00:00 +0000 +++ src/tests/stub_SBufDetailedStats.cc 2013-11-22 22:04:23 +0000 @@ -0,0 +1,12 @@ +#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) === modified file 'src/tests/testStatHist.cc' --- src/tests/testStatHist.cc 2013-10-25 00:13:46 +0000 +++ src/tests/testStatHist.cc 2013-11-23 11:44:28 +0000 @@ -73,3 +73,25 @@ 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); + +} === modified file 'src/tests/testStatHist.h' --- src/tests/testStatHist.h 2012-08-28 13:00:30 +0000 +++ src/tests/testStatHist.h 2013-11-23 11:20:47 +0000 @@ -13,6 +13,7 @@ CPPUNIT_TEST( testStatHistBaseEquality ); CPPUNIT_TEST( testStatHistBaseAssignment ); CPPUNIT_TEST( testStatHistLog ); + CPPUNIT_TEST( testStatHistSum ); CPPUNIT_TEST_SUITE_END(); public: @@ -21,6 +22,7 @@ void testStatHistBaseEquality(); void testStatHistBaseAssignment(); void testStatHistLog(); + void testStatHistSum(); }; #endif /* TESTSTATHIST_H_ */