This is a proof of concept patch. On the way to making ufsdump link a much smaller section of squid, I found that anything using Packer requires all of the store.
This patch addresses that by adding a replacement for Packer using the C
++ ostream facility:
StoreEntryStream stream(anEntry);
stream << "some text" << std::setw(4) <<"!";
stream.flush();
is equivalent to:
Packer p;
packerToStoreInit(p, anEntry);
packerPrintf("some text %-4s" , "!");
packerClean(p);
but doesn't require typecasting variables that change width from 32 to
64 bit platforms.
It still requires store.o linked in, but the only remaining call to need
that is the storeLockObject call, and I plan to fix that shortly.
Thoughts? opinions?
Rob
--
GPG key available at: <http://www.robertcollins.net/keys.txt>.
=== added file 'b/src/StoreEntryStream.h' --- /dev/null +++ b/src/StoreEntryStream.h @@ -0,0 +1,117 @@ + +/* + * $Id$ + * + * + * 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. + * + */ + +#ifndef SQUID_STORE_ENTRY_STREAM_H +#define SQUID_STORE_ENTRY_STREAM_H + +#include "Store.h" + +#include <ostream> + +/* + * This class provides a streambuf interface for writing + * to StoreEntries. Typical use is via a StoreEntryStream + * rather than direct manipulation + */ +class StoreEntryStreamBuf : public std::streambuf +{ +public: + StoreEntryStreamBuf(StoreEntry *anEntry) : anEntry(anEntry) + { + storeLockObject(anEntry); + anEntry->buffer(); + } + ~StoreEntryStreamBuf() + { + storeUnlockObject(anEntry); + } + +protected: + /* flush the current buffer and the character that is overflowing + * to the store entry. + */ + virtual char overflow(char aChar = traits_type::eof()) + { + std::streamsize pending(pptr() - pbase()); + if (pending && sync ()) + return traits_type::eof(); + if (aChar != traits_type::eof()) + { + char chars[1] = {aChar}; + if (aChar != traits_type::eof()) + anEntry->append(chars, 1); + } + pbump (-pending); // Reset pptr(). + return aChar; + } + + /* push the buffer to the store */ + virtual int sync() + { + std::streamsize pending(pptr() - pbase()); + if (pending) + anEntry->append(pbase(), pending); + anEntry->flush(); + return 0; + } + + /* write multiple characters to the store entry + * - this is an optimisation method. + */ + virtual std::streamsize xsputn(const char * chars, std::streamsize number) + { + if (number) + anEntry->append(chars, number); + return number; + } + +private: + StoreEntry *anEntry; + +}; + +class StoreEntryStream : public std::ostream +{ + +public: + /* create a stream for writing text etc into anEntry */ + StoreEntryStream(StoreEntry *anEntry) : _buffer(anEntry) { this->init(&_buffer);} + +private: + StoreEntryStreamBuf _buffer; + +public: + StoreEntryStreamBuf * rdbuf() const { return const_cast<StoreEntryStreamBuf *>(&_buffer); } +}; + +#endif /* SQUID_STORE_ENTRY_STREAM_H */ === added file 'b/src/tests/testStoreEntryStream.cc' --- /dev/null +++ b/src/tests/testStoreEntryStream.cc @@ -0,0 +1,81 @@ +#include "squid.h" +#include "Mem.h" +#include "testStore.h" +#include "testStoreEntryStream.h" +#include "Store.h" +#include "StoreEntryStream.h" + +#include <iomanip> + +#include <cppunit/TestAssert.h> + +CPPUNIT_TEST_SUITE_REGISTRATION( testStoreEntryStream ); + +/* class that captures various call data for test analysis */ +class CapturingStoreEntry : public StoreEntry +{ +public: + MEMPROXY_CLASS(CapturingStoreEntry); + + CapturingStoreEntry() : _buffer_calls(0), _flush_calls(0) {} + + String _appended_text; + int _buffer_calls; + int _flush_calls; + + virtual void buffer() + { + _buffer_calls += 1; + } + + virtual void flush() + { + _flush_calls += 1; + } + + virtual void append(char const * buf, int len) + { + _appended_text.append(buf, len); + } +}; + +MEMPROXY_CLASS_INLINE(CapturingStoreEntry); + + +/* init memory pools */ +struct Initer +{ + Initer() {Mem::Init();} +}; + +static Initer ensure_mempools; + +std::ostream & +operator<<(std::ostream& os, String const &aString) +{ + os << aString.buf(); + return os; +} + +void +testStoreEntryStream::testGetStream() +{ + /* Setup a store root so we can create a StoreEntry */ + StorePointer aStore (new TestStore); + Store::Root(aStore); + + CapturingStoreEntry * anEntry = new CapturingStoreEntry(); + StoreEntryStream stream(anEntry); + CPPUNIT_ASSERT_EQUAL(1, anEntry->_buffer_calls); + CPPUNIT_ASSERT_EQUAL(0, anEntry->_flush_calls); + stream << "some text" << std::setw(4) << "!"; + CPPUNIT_ASSERT_EQUAL(1, anEntry->_buffer_calls); + CPPUNIT_ASSERT_EQUAL(0, anEntry->_flush_calls); + stream.flush(); + CPPUNIT_ASSERT_EQUAL(1, anEntry->_buffer_calls); + CPPUNIT_ASSERT_EQUAL(1, anEntry->_flush_calls); + CPPUNIT_ASSERT_EQUAL(String("some text !"), anEntry->_appended_text); + delete anEntry; + + Store::Root(NULL); +} === added file 'b/src/tests/testStoreEntryStream.h' --- /dev/null +++ b/src/tests/testStoreEntryStream.h @@ -0,0 +1,24 @@ + +#ifndef SQUID_SRC_TEST_STORE_ENTRY_STREAM_H +#define SQUID_SRC_TEST_STORE_ENTRY_STREAM_H + +#include <cppunit/extensions/HelperMacros.h> + +/* + * test StoreEntryStream + */ + +class testStoreEntryStream : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testStoreEntryStream ); + CPPUNIT_TEST( testGetStream ); + CPPUNIT_TEST_SUITE_END(); + +public: + +protected: + void testGetStream(); +}; + +#endif + === added file 'b/src/tests/testString.cc' --- /dev/null +++ b/src/tests/testString.cc @@ -0,0 +1,60 @@ +#include "squid.h" +#include "Mem.h" +#include "SquidString.h" +#include "testString.h" + +CPPUNIT_TEST_SUITE_REGISTRATION( testString ); + +/* let this test link sanely */ +void +eventAdd(const char *name, EVH * func, void *arg, double when, int, bool cbdata) +{ +} + +/* init memory pools */ +struct Initer +{ + Initer() {Mem::Init();} +}; + +static Initer ensure_mempools; + +void +testString::testCmpDefault() +{ + String left, right; + /* two default strings are equal */ + CPPUNIT_ASSERT(!left.cmp(right)); + CPPUNIT_ASSERT(!left.cmp(NULL)); + CPPUNIT_ASSERT(!left.cmp(NULL, 1)); +} + +void +testString::testCmpEmptyString() +{ + String left(""); + String right; + /* an empty string ("") is equal to a default string */ + CPPUNIT_ASSERT(!left.cmp(right)); + CPPUNIT_ASSERT(!left.cmp(NULL)); + CPPUNIT_ASSERT(!left.cmp(NULL, 1)); + /* reverse the order to catch corners */ + CPPUNIT_ASSERT(!right.cmp(left)); + CPPUNIT_ASSERT(!right.cmp("")); + CPPUNIT_ASSERT(!right.cmp("", 1)); +} + +void +testString::testCmpNotEmptyDefault() +{ + String left("foo"); + String right; + /* empty string sorts before everything */ + CPPUNIT_ASSERT(left.cmp(right) > 0); + CPPUNIT_ASSERT(left.cmp(NULL) > 0); + CPPUNIT_ASSERT(left.cmp(NULL, 1) > 0); + /* reverse for symmetry tests */ + CPPUNIT_ASSERT(right.cmp(left) < 0); + CPPUNIT_ASSERT(right.cmp("foo") < 0); + CPPUNIT_ASSERT(right.cmp("foo", 1) < 0); +} === added file 'b/src/tests/testString.h' --- /dev/null +++ b/src/tests/testString.h @@ -0,0 +1,28 @@ + +#ifndef SQUID_SRC_TEST_STRING_H +#define SQUID_SRC_TEST_STRING_H + +#include <cppunit/extensions/HelperMacros.h> + +/* + * test the store framework + */ + +class testString : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testString ); + CPPUNIT_TEST( testCmpDefault ); + CPPUNIT_TEST( testCmpEmptyString ); + CPPUNIT_TEST( testCmpNotEmptyDefault ); + CPPUNIT_TEST_SUITE_END(); + +public: + +protected: + void testCmpDefault(); + void testCmpEmptyString(); + void testCmpNotEmptyDefault(); +}; + +#endif + === modified file 'a/src/Makefile.am' --- a/src/Makefile.am +++ b/src/Makefile.am @@ -562,6 +563,7 @@ MemBuf.cci \ MemBuf.h \ Store.cci \ + StoreEntryStream.h \ String.cci \ SquidString.h @@ -1017,6 +1017,7 @@ tests/testBoilerplate \ tests/testHeaders \ tests/testStore \ + tests/testString \ @STORE_TESTS@ tests_testAuth_SOURCES= tests/testAuth.cc tests/testMain.cc tests/testAuth.h $(TESTSOURCES) \ @@ -1147,6 +1148,7 @@ tests/testHeader_HttpHeader.cc \ tests/testHeader_HttpHeaderRange.cc \ tests/testHeader_HttpReply.cc \ + tests/testHeader_StoreEntryStream.cc \ tests/testHeader_wordlist.cc tests_testHeaders_SOURCES= tests/testMain.cc $(HEADERS_TO_TEST) tests_testHeaders_LDADD= \ @@ -1200,6 +1202,8 @@ tests/stub_MemObject.cc \ tests/testStore.cc \ tests/testStore.h \ + tests/testStoreEntryStream.cc \ + tests/testStoreEntryStream.h \ tests/testStoreController.cc \ tests/testStoreController.h \ tests/testStoreHashIndex.cc \ @@ -1217,6 +1221,25 @@ @SSLLIB@ tests_testStore_LDFLAGS = $(LIBADD_DL) tests_testStore_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ + @SQUID_CPPUNIT_LA@ + +# string needs mem.cc. mem.cc wants cache_manage +tests_testString_SOURCES= \ + mem.cc \ + String.cc \ + tests/stub_cache_manager.cc \ + tests/testMain.cc \ + tests/testString.cc \ + tests/testString.h \ + $(TESTSOURCES) + +tests_testString_LDADD= \ + -L../lib -lmiscutil \ + @REGEXLIB@ \ + @SQUID_CPPUNIT_LA@ \ + @SSLLIB@ +tests_testString_LDFLAGS = $(LIBADD_DL) +tests_testString_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ @SQUID_CPPUNIT_LA@ SWAP_TEST_SOURCES = \ === modified file 'a/src/Mem.h' --- a/src/Mem.h +++ b/src/Mem.h @@ -36,6 +36,10 @@ #ifndef SQUID_MEM #define SQUID_MEM +#include <iosfwd> + +class Packer; + class Mem { @@ -43,8 +47,8 @@ static void Init(); static void Stats(StoreEntry *); static void CleanIdlePools(void *unused); - static void Report(StoreEntry *); - static void PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, StoreEntry * e); + static void Report(std::ostream &); + static void PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, std::ostream &); }; #endif /* SQUID_MEM */ === modified file 'a/src/Store.h' --- a/src/Store.h +++ b/src/Store.h @@ -33,6 +33,10 @@ #ifndef SQUID_STORE_H #define SQUID_STORE_H + +#include "squid.h" + +#include <ostream> #include "StoreIOBuffer.h" #include "Range.h" @@ -136,6 +140,12 @@ ESIElement::Pointer cachedESITree; #endif + /* append bytes to the buffer */ + virtual void append(char const *, int len); + /* disable sending content to the clients */ + virtual void buffer(); + /* flush any buffered content */ + virtual void flush(); private: static MemImplementingAllocator *pool; @@ -177,6 +187,7 @@ }; typedef void (*STOREGETCLIENT) (StoreEntry *, void *cbdata); + /* Abstract base class that will replace the whole store and swapdir interface. */ === modified file 'a/src/String.cci' --- a/src/String.cci +++ b/src/String.cci @@ -73,18 +73,41 @@ int String::cmp (char const *aString) const { + /* strcmp fails on NULLS */ + if (size() == 0 && (aString == NULL || aString[0] == '\0')) + return 0; + if (size() == 0) + return -1; + if (aString == NULL || aString[0] == '\0') + return 1; return strcmp(buf(), aString); } int String::cmp (char const *aString, size_t count) const { + /* always the same at length 0 */ + if (count == 0) + return 0; + if (size() == 0 && (aString == NULL || aString[0] == '\0')) + return 0; + if (size() == 0) + return -1; + if (aString == NULL || aString[0] == '\0') + return 1; return strncmp(buf(), aString, count); } int String::cmp (String const &aString) const { + /* strcmp fails on NULLS */ + if (size() == 0 && aString.size() == 0) + return 0; + if (size() == 0) + return -1; + if (aString.size() == 0) + return 1; return strcmp(buf(), aString.buf()); } === modified file 'a/src/mem.cc' --- a/src/mem.cc +++ b/src/mem.cc @@ -34,15 +34,20 @@ */ #include "squid.h" + +#include <iomanip> +#include <ostream> + #include "Mem.h" #include "memMeter.h" #include "Store.h" +#include "StoreEntryStream.h" #include "MemBuf.h" /* module globals */ /* local prototypes */ -static void memStringStats(StoreEntry * sentry); +static void memStringStats(std::ostream &); /* module locals */ static MemImplementingAllocator *MemPools[MEM_MAX]; @@ -86,54 +91,48 @@ /* local routines */ static void -memStringStats(StoreEntry * sentry) -{ - const char *pfmt = "%-20s\t %d\t %d\n"; +memStringStats(std::ostream &stream) +{ int i; int pooled_count = 0; size_t pooled_volume = 0; /* heading */ - storeAppendPrintf(sentry, - "String Pool\t Impact\t\t\n" - " \t (%%strings)\t (%%volume)\n"); + stream << "String Pool\t Impact\t\t\n \t (%%strings)\t (%%volume)\n"; /* table body */ for (i = 0; i < mem_str_pool_count; i++) { const MemAllocator *pool = StrPools[i].pool; const int plevel = pool->getMeter().inuse.level; - storeAppendPrintf(sentry, pfmt, - pool->objectType(), - xpercentInt(plevel, StrCountMeter.level), - xpercentInt(plevel * pool->objectSize(), StrVolumeMeter.level)); + stream << std::setw(20) << std::left << pool->objectType(); + stream << std::right << "\t " << xpercentInt(plevel, StrCountMeter.level); + stream << "\t " << xpercentInt(plevel * pool->objectSize(), StrVolumeMeter.level) << "\n"; pooled_count += plevel; pooled_volume += plevel * pool->objectSize(); } /* malloc strings */ - storeAppendPrintf(sentry, pfmt, - "Other Strings", - xpercentInt(StrCountMeter.level - pooled_count, StrCountMeter.level), - xpercentInt(StrVolumeMeter.level - pooled_volume, StrVolumeMeter.level)); - - storeAppendPrintf(sentry, "\n"); + stream << std::setw(20) << std::left << "Other Strings"; + stream << std::right << "\t "; + stream << xpercentInt(StrCountMeter.level - pooled_count, StrCountMeter.level) << "\t "; + stream << xpercentInt(StrVolumeMeter.level - pooled_volume, StrVolumeMeter.level) << "\n\n"; } static void -memBufStats(StoreEntry * sentry) -{ - storeAppendPrintf(sentry, "Large buffers: %ld (%ld KB)\n", - (long int) HugeBufCountMeter.level, - (long int) HugeBufVolumeMeter.level / 1024); +memBufStats(std::ostream & stream) +{ + stream << "Large buffers: " << + HugeBufCountMeter.level << " (" << + HugeBufVolumeMeter.level / 1024 << " KB)\n"; } void Mem::Stats(StoreEntry * sentry) { - storeBuffer(sentry); - Report(sentry); - memStringStats(sentry); - memBufStats(sentry); - storeBufferFlush(sentry); + StoreEntryStream stream(sentry); + Report(stream); + memStringStats(stream); + memBufStats(stream); + stream.flush(); } /* @@ -537,18 +536,21 @@ /* MemPoolMeter */ void -Mem::PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, StoreEntry * e) +Mem::PoolReport(const MemPoolStats * mp_st, const MemPoolMeter * AllMeter, std::ostream &stream) { int excess = 0; int needed = 0; MemPoolMeter *pm = mp_st->meter; - - storeAppendPrintf(e, "%-20s\t %4d\t ", - mp_st->label, mp_st->obj_size); + + stream << std::setw(20) << std::left << mp_st->label; + stream << "\t " << std::setw(4) << std::right; + stream << mp_st->obj_size; /* Chunks */ - storeAppendPrintf(e, "%4d\t %4d\t ", - toKB(mp_st->obj_size * mp_st->chunk_capacity), mp_st->chunk_capacity); + stream << "\t " << std::setw(4); + stream << toKB(mp_st->obj_size * mp_st->chunk_capacity); + stream << "\t " << std::setw(4) << mp_st->chunk_capacity; + stream << "\t "; if (mp_st->chunk_capacity) { needed = mp_st->items_inuse / mp_st->chunk_capacity; @@ -559,9 +561,11 @@ excess = mp_st->chunks_inuse - needed; } - storeAppendPrintf(e, "%4d\t %4d\t %4d\t %4d\t %.1f\t ", - mp_st->chunks_alloc, mp_st->chunks_inuse, mp_st->chunks_free, mp_st->chunks_partial, - xpercent(excess, needed)); + stream << std::setw(4) << mp_st->chunks_alloc << "\t "; + stream << std::setw(4) << mp_st->chunks_inuse << "\t "; + stream << std::setw(4) << mp_st->chunks_free << "\t "; + stream << std::setw(4) << mp_st->chunks_partial << "\t "; + stream << std::setprecision(1) << xpercent(excess, needed) << "\t "; /* * Fragmentation calculation: * needed = inuse.level / chunk_capacity @@ -570,33 +574,26 @@ * * Fragm = (alloced - (inuse / obj_ch) ) / alloced */ - - storeAppendPrintf(e, - "%d\t %ld\t %ld\t %.2f\t %.1f\t" /* alloc */ - "%d\t %ld\t %ld\t %.2f\t %.1f\t" /* in use */ - "%d\t %ld\t %ld\t" /* idle */ - "%.0f\t %.1f\t %.1f\t %.1f\n", /* saved */ - /* alloc */ - mp_st->items_alloc, - (long) toKB(mp_st->obj_size * pm->alloc.level), - (long) toKB(mp_st->obj_size * pm->alloc.hwater_level), - (double) ((squid_curtime - pm->alloc.hwater_stamp) / 3600.), - xpercent(mp_st->obj_size * pm->alloc.level, AllMeter->alloc.level), - /* in use */ - mp_st->items_inuse, - (long) toKB(mp_st->obj_size * pm->inuse.level), - (long) toKB(mp_st->obj_size * pm->inuse.hwater_level), - (double) ((squid_curtime - pm->inuse.hwater_stamp) / 3600.), - xpercent(pm->inuse.level, pm->alloc.level), - /* idle */ - mp_st->items_idle, - (long) toKB(mp_st->obj_size * pm->idle.level), - (long) toKB(mp_st->obj_size * pm->idle.hwater_level), - /* saved */ - pm->gb_saved.count, - xpercent(pm->gb_saved.count, AllMeter->gb_saved.count), - xpercent(pm->gb_saved.bytes, AllMeter->gb_saved.bytes), - xdiv(pm->gb_saved.count - pm->gb_osaved.count, xm_deltat)); + /* allocated */ + stream << mp_st->items_alloc << "\t "; + stream << toKB(mp_st->obj_size * pm->alloc.level) << "\t "; + stream << toKB(mp_st->obj_size * pm->alloc.hwater_level) << "\t "; + stream << std::setprecision(2) << ((squid_curtime - pm->alloc.hwater_stamp) / 3600.); + stream << "\t " << std::setprecision(1) << xpercent(mp_st->obj_size * pm->alloc.level, AllMeter->alloc.level); + /* in use */ + stream << "\t" << mp_st->items_inuse << "\t "; + stream << toKB(mp_st->obj_size * pm->inuse.level) << "\t "; + stream << toKB(mp_st->obj_size * pm->inuse.hwater_level) << "\t "; + stream << std::setprecision(2) << ((squid_curtime - pm->inuse.hwater_stamp) / 3600.); + stream << "\t " << std::setprecision(1) << xpercent(pm->inuse.level, pm->alloc.level); + /* idle */ + stream << "\t" << mp_st->items_idle << "\t " << toKB(mp_st->obj_size * pm->idle.level); + stream << "\t " << toKB(mp_st->obj_size * pm->idle.hwater_level) << "\t"; + /* saved */ + stream << std::setprecision(0) << pm->gb_saved.count << "\t "; + stream << std::setprecision(1) << xpercent(pm->gb_saved.count, AllMeter->gb_saved.count); + stream << "\t " << xpercent(pm->gb_saved.bytes, AllMeter->gb_saved.bytes) << "\t "; + stream << xdiv(pm->gb_saved.count - pm->gb_osaved.count, xm_deltat) << "\n"; pm->gb_osaved.count = pm->gb_saved.count; } @@ -632,7 +629,7 @@ } void -Mem::Report(StoreEntry * e) +Mem::Report(std::ostream &stream) { static char buf[64]; static MemPoolStats mp_stats; @@ -642,26 +639,25 @@ MemAllocator *pool; /* caption */ - storeAppendPrintf(e, "Current memory usage:\n"); + stream << "Current memory usage:\n"; /* heading */ - storeAppendPrintf(e, - "Pool\t Obj Size\t" - "Chunks\t\t\t\t\t\t\t" - "Allocated\t\t\t\t\t" - "In Use\t\t\t\t\t" - "Idle\t\t\t" - "Allocations Saved\t\t\t" - "Hit Rate\t" - "\n" - " \t (bytes)\t" - "KB/ch\t obj/ch\t" - "(#)\t used\t free\t part\t %%Frag\t " - "(#)\t (KB)\t high (KB)\t high (hrs)\t %%Tot\t" - "(#)\t (KB)\t high (KB)\t high (hrs)\t %%alloc\t" - "(#)\t (KB)\t high (KB)\t" - "(#)\t %%cnt\t %%vol\t" - "(#) / sec\t" - "\n"); + stream << "Pool\t Obj Size\t" + "Chunks\t\t\t\t\t\t\t" + "Allocated\t\t\t\t\t" + "In Use\t\t\t\t\t" + "Idle\t\t\t" + "Allocations Saved\t\t\t" + "Hit Rate\t" + "\n" + " \t (bytes)\t" + "KB/ch\t obj/ch\t" + "(#)\t used\t free\t part\t %%Frag\t " + "(#)\t (KB)\t high (KB)\t high (hrs)\t %%Tot\t" + "(#)\t (KB)\t high (KB)\t high (hrs)\t %%alloc\t" + "(#)\t (KB)\t high (KB)\t" + "(#)\t %%cnt\t %%vol\t" + "(#) / sec\t" + "\n"; xm_deltat = current_dtime - xm_time; xm_time = current_dtime; @@ -691,7 +687,7 @@ qsort(sortme, npools, sizeof(*sortme), MemPoolReportSorter); for (int i = 0; i< npools; i++) { - PoolReport(&sortme[i], mp_total.TheMeter, e); + PoolReport(&sortme[i], mp_total.TheMeter, stream); } xfree(sortme); @@ -711,17 +707,17 @@ mp_stats.items_idle = mp_total.tot_items_idle; mp_stats.overhead = mp_total.tot_overhead; - PoolReport(&mp_stats, mp_total.TheMeter, e); + PoolReport(&mp_stats, mp_total.TheMeter, stream); /* Cumulative */ - storeAppendPrintf(e, "Cumulative allocated volume: %s\n", double_to_str(buf, 64, mp_total.TheMeter->gb_saved.bytes)); + stream << "Cumulative allocated volume: "<< double_to_str(buf, 64, mp_total.TheMeter->gb_saved.bytes) << "\n"; /* overhead */ - storeAppendPrintf(e, "Current overhead: %d bytes (%.3f%%)\n", - mp_total.tot_overhead, xpercent(mp_total.tot_overhead, mp_total.TheMeter->inuse.level)); + stream << "Current overhead: " << mp_total.tot_overhead << " bytes (" << + std::setprecision(3) << xpercent(mp_total.tot_overhead, mp_total.TheMeter->inuse.level) << "%%)\n"; /* limits */ - storeAppendPrintf(e, "Idle pool limit: %.2f MB\n", toMB(mp_total.mem_idle_limit)); + stream << "Idle pool limit: " << std::setprecision(2) << toMB(mp_total.mem_idle_limit) << " MB\n"; /* limits */ - storeAppendPrintf(e, "Total Pools created: %d\n", mp_total.tot_pools_alloc); - storeAppendPrintf(e, "Pools ever used: %d (shown above)\n", mp_total.tot_pools_alloc - not_used); - storeAppendPrintf(e, "Currently in use: %d\n", mp_total.tot_pools_inuse); -} + stream << "Total Pools created: " << mp_total.tot_pools_alloc << "\n"; + stream << "Pools ever used: " << mp_total.tot_pools_alloc - not_used << " (shown above)\n"; + stream << "Currently in use: " << mp_total.tot_pools_inuse << "\n"; +} === modified file 'a/src/store.cc' --- a/src/store.cc +++ b/src/store.cc @@ -858,14 +858,20 @@ PROF_stop(StoreEntry_write); } +/* Legacy call for appending data to a store entry */ +void +storeAppend(StoreEntry * e, const char *buf, int len) +{ + e->append(buf, len); +} + /* Append incoming data from a primary server to an entry. */ void -storeAppend(StoreEntry * e, const char *buf, int len) -{ - MemObject *mem = e->mem_obj; - assert(mem != NULL); +StoreEntry::append(char const *buf, int len) +{ + assert(mem_obj != NULL); assert(len >= 0); - assert(e->store_status == STORE_PENDING); + assert(store_status == STORE_PENDING); StoreIOBuffer tempBuffer; tempBuffer.data = (char *)buf; @@ -874,9 +880,10 @@ * XXX sigh, offset might be < 0 here, but it gets "corrected" * later. This offset crap is such a mess. */ - tempBuffer.offset = mem->endOffset() - (e->getReply() ? e->getReply()->hdr_sz : 0); - e->write(tempBuffer); -} + tempBuffer.offset = mem_obj->endOffset() - (getReply() ? getReply()->hdr_sz : 0); + write(tempBuffer); +} + void #if STDC_HEADERS @@ -1667,20 +1674,33 @@ e->mem_obj = new MemObject(url, log_url); } +/* DEPRECATED: please use entry->buffer() */ +void +storeBuffer(StoreEntry * e) +{ + e->buffer(); +} + /* this just sets DELAY_SENDING */ void -storeBuffer(StoreEntry * e) -{ - EBIT_SET(e->flags, DELAY_SENDING); +StoreEntry::buffer() +{ + EBIT_SET(flags, DELAY_SENDING); +} + +/* DEPRECATED - please use e->flush(); */ +void storeBufferFlush(StoreEntry * e) +{ + e->flush(); } /* this just clears DELAY_SENDING and Invokes the handlers */ void -storeBufferFlush(StoreEntry * e) -{ - if (EBIT_TEST(e->flags, DELAY_SENDING)) { - EBIT_CLR(e->flags, DELAY_SENDING); - InvokeHandlers(e); +StoreEntry::flush() +{ + if (EBIT_TEST(flags, DELAY_SENDING)) { + EBIT_CLR(flags, DELAY_SENDING); + InvokeHandlers(this); } } === modified file 'a/src/store_key_md5.cc' --- a/src/store_key_md5.cc +++ b/src/store_key_md5.cc @@ -104,8 +104,7 @@ static cache_key digest[MD5_DIGEST_CHARS]; MD5_CTX M; assert(id > 0); - debug(20, 3) ("storeKeyPrivate: %s %s\n", - RequestMethodStr[method], url); + debugs(20, 3, "storeKeyPrivate: " << RequestMethodStr[method] << url); MD5Init(&M); MD5Update(&M, (unsigned char *) &id, sizeof(id)); MD5Update(&M, (unsigned char *) &method, sizeof(method)); === modified file 'a/src/tests/testStore.cc' --- a/src/tests/testStore.cc +++ b/src/tests/testStore.cc @@ -3,47 +3,6 @@ #include "Store.h" CPPUNIT_TEST_SUITE_REGISTRATION( testStore ); - -/* subclass of Store to allow testing of methods without having all the - * other components live - */ - -class TestStore : public Store -{ - -public: - TestStore() : statsCalled (false) {} - - bool statsCalled; - - virtual int callback(); - - virtual StoreEntry* get - (const cache_key*); - - virtual void get - (String, void (*)(StoreEntry*, void*), void*); - - virtual void init(); - -virtual void maintain() {}; - - virtual size_t maxSize() const; - - virtual size_t minSize() const; - - virtual void stat(StoreEntry &) const; /* output stats to the provided store entry */ - - virtual void reference(StoreEntry &){} /* Reference this object */ - - virtual void dereference(StoreEntry &){} /* Unreference this object */ - - virtual void updateSize(size_t size, int sign) {} - - virtual StoreSearch *search(String const url, HttpRequest *); -}; - -typedef RefCount<TestStore> TestStorePointer; int TestStore::callback() === modified file 'a/src/tests/testStore.h' --- a/src/tests/testStore.h +++ b/src/tests/testStore.h @@ -2,7 +2,11 @@ #ifndef SQUID_SRC_TEST_STORE_H #define SQUID_SRC_TEST_STORE_H +#include "squid.h" +#include "Store.h" + #include <cppunit/extensions/HelperMacros.h> + /* * test the store framework @@ -26,5 +30,48 @@ void testMaxSize(); }; + +/* subclass of Store to allow testing of methods without having all the + * other components live + */ + +class TestStore : public Store +{ + +public: + TestStore() : statsCalled (false) {} + + bool statsCalled; + + virtual int callback(); + + virtual StoreEntry* get + (const cache_key*); + + virtual void get + (String, void (*)(StoreEntry*, void*), void*); + + virtual void init(); + +virtual void maintain() {}; + + virtual size_t maxSize() const; + + virtual size_t minSize() const; + + virtual void stat(StoreEntry &) const; /* output stats to the provided store entry */ + + virtual void reference(StoreEntry &){} /* Reference this object */ + + virtual void dereference(StoreEntry &){} /* Unreference this object */ + + virtual void updateSize(size_t size, int sign) {} + + virtual StoreSearch *search(String const url, HttpRequest *); +}; + +typedef RefCount<TestStore> TestStorePointer; + + #endif
signature.asc
Description: This is a digitally signed message part
