=== 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 + +/* + * 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(&_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 + +#include + +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 + +/* + * 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 + +/* + * 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 + +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 #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 +#include + #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 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 + /* * 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 TestStorePointer; + + #endif