From: Alex Rousskov Date: Mon, 17 Mar 2014 21:03:04 +0000 (-0600) Subject: Undo trunk r13270: "Refactor Vector and Stack to STL counterparts" X-Git-Tag: SQUID_3_5_0_1~170^2~17 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=4e4c52effcd62c2fdcce4703dd9e839a80864d1a;p=thirdparty%2Fsquid.git Undo trunk r13270: "Refactor Vector and Stack to STL counterparts" to avoid stability issues related to std::vector migration. --- diff --git a/include/MemPoolMalloc.h b/include/MemPoolMalloc.h index 43064203ea..2999dd4620 100644 --- a/include/MemPoolMalloc.h +++ b/include/MemPoolMalloc.h @@ -22,8 +22,6 @@ #include "MemPool.h" -#include - /// \ingroup MemPoolsAPI class MemPoolMalloc : public MemImplementingAllocator { @@ -44,7 +42,7 @@ protected: virtual void *allocate(); virtual void deallocate(void *, bool aggressive); private: - std::stack freelist; + Stack freelist; }; #endif /* _MEM_POOL_MALLOC_H_ */ diff --git a/include/Stack.h b/include/Stack.h new file mode 100644 index 0000000000..fe39f6680f --- /dev/null +++ b/include/Stack.h @@ -0,0 +1,67 @@ +/* + * AUTHOR: Alex Rousskov + * + * 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_STACK_H +#define SQUID_STACK_H + +#include "base/Vector.h" + +/* RBC: 20030714 Composition might be better long-term, but for now, + * there's no reason to do so. + */ + +template + +class Stack : public Vector +{ +public: + using Vector::count; + using Vector::items; + typedef typename Vector::value_type value_type; + typedef typename Vector::pointer pointer; + value_type pop() { + if (!count) + return value_type(); + + value_type result = items[--count]; + + this->items[count] = value_type(); + + return result; + } + + /* todo, fatal on empty Top call */ + value_type top() const { + return count ? items[count - 1] : value_type(); + } +}; + +#endif /* SQUID_STACK_H */ diff --git a/include/splay.h b/include/splay.h index daafdd19b6..ea4f2c3e03 100644 --- a/include/splay.h +++ b/include/splay.h @@ -3,9 +3,7 @@ #if defined(__cplusplus) -#include "fatal.h" - -#include +#include "Stack.h" template class SplayNode @@ -378,7 +376,7 @@ private: void advance(); void addLeftPath(SplayNode *aNode); void init(SplayNode *); - std::stack *> toVisit; + Stack *> toVisit; }; template @@ -391,12 +389,7 @@ template bool SplayConstIterator::operator == (SplayConstIterator const &right) const { - if (toVisit.empty() && right.toVisit.empty()) - return true; - if (!toVisit.empty() && !right.toVisit.empty()) - return toVisit.top() == right.toVisit.top(); - // only one of the two is empty - return false; + return toVisit.top() == right.toVisit.top(); } template @@ -428,21 +421,19 @@ template void SplayConstIterator::advance() { - if (toVisit.empty()) + if (toVisit.size() == 0) return; toVisit.pop(); - if (toVisit.empty()) + if (toVisit.size() == 0) return; - // not empty - SplayNode *currentNode = toVisit.top(); - toVisit.pop(); + SplayNode *currentNode = toVisit.pop(); addLeftPath(currentNode->right); - toVisit.push(currentNode); + toVisit.push_back(currentNode); } template @@ -453,7 +444,7 @@ SplayConstIterator::addLeftPath(SplayNode *aNode) return; do { - toVisit.push(aNode); + toVisit.push_back(aNode); aNode = aNode->left; } while (aNode != NULL); } diff --git a/lib/MemPoolMalloc.cc b/lib/MemPoolMalloc.cc index f0fe52fe98..5a442f4e20 100644 --- a/lib/MemPoolMalloc.cc +++ b/lib/MemPoolMalloc.cc @@ -46,11 +46,7 @@ extern time_t squid_curtime; void * MemPoolMalloc::allocate() { - void *obj = NULL; - if (!freelist.empty()) { - obj = freelist.top(); - freelist.pop(); - } + void *obj = freelist.pop(); if (obj) { memMeterDec(meter.idle); ++saved_calls; @@ -76,7 +72,7 @@ MemPoolMalloc::deallocate(void *obj, bool aggressive) if (doZero) memset(obj, 0, obj_size); memMeterInc(meter.idle); - freelist.push(obj); + freelist.push_back(obj); } } @@ -132,9 +128,7 @@ MemPoolMalloc::idleTrigger(int shift) const void MemPoolMalloc::clean(time_t maxage) { - while (!freelist.empty()) { - void *obj = freelist.top(); - freelist.pop(); + while (void *obj = freelist.pop()) { memMeterDec(meter.idle); memMeterDec(meter.alloc); xfree(obj); diff --git a/src/DelayUser.h b/src/DelayUser.h index 9bc88f411d..6ac274791c 100644 --- a/src/DelayUser.h +++ b/src/DelayUser.h @@ -38,6 +38,7 @@ #include "auth/Gadgets.h" #include "auth/User.h" +#include "base/Vector.h" #include "CompositePoolNode.h" #include "DelayBucket.h" #include "DelayIdComposite.h" diff --git a/src/Generic.h b/src/Generic.h index 1f7fbbf99b..5e3329abd1 100644 --- a/src/Generic.h +++ b/src/Generic.h @@ -58,6 +58,18 @@ T& for_each(dlink_list const &collection, T& visitor) return visitor; } +template +class Stack; + +template +T& for_each(Stack const &collection, T& visitor) +{ + for (size_t index = 0; index < collection.count; ++index) + visitor(*(typename T::argument_type const *)collection.items[index]); + + return visitor; +}; + /* RBC 20030718 - use this to provide instance expecting classes a pointer to a * singleton */ diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc index 56eb4b32e6..26677530c6 100644 --- a/src/HttpHeader.cc +++ b/src/HttpHeader.cc @@ -52,10 +52,6 @@ #include -/* XXX: the whole set of API managing the entries vector should be rethought - * after the parse4r-ng effort is complete. - */ - /* * On naming conventions: * @@ -441,6 +437,8 @@ HttpHeader::operator =(const HttpHeader &other) void HttpHeader::clean() { + HttpHeaderPos pos = HttpHeaderInitPos; + HttpHeaderEntry *e; assert(owner > hoNone && owner < hoEnd); debugs(55, 7, "cleaning hdr: " << this << " owner: " << owner); @@ -466,19 +464,18 @@ HttpHeader::clean() HttpHeaderStats[owner].busyDestroyedCount += entries.size() > 0; } // if (owner <= hoReply) - for (std::vector::iterator i = entries.begin(); i != entries.end(); ++i) { - HttpHeaderEntry *e = *i; - if (e == NULL) - continue; + while ((e = getEntry(&pos))) { + /* tmp hack to try to avoid coredumps */ + if (e->id < 0 || e->id >= HDR_ENUM_END) { - debugs(55, DBG_CRITICAL, "BUG: invalid entry (" << e->id << "). Ignored."); + debugs(55, DBG_CRITICAL, "HttpHeader::clean BUG: entry[" << pos << "] is invalid (" << e->id << "). Ignored."); } else { if (owner <= hoReply) HttpHeaderStats[owner].fieldTypeDistr.count(e->id); + /* yes, this deletion leaves us in an inconsistent state */ delete e; } } - entries.clear(); httpHeaderMaskInit(&mask, 0); len = 0; diff --git a/src/Makefile.am b/src/Makefile.am index c0568c1ead..400f3153d5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1077,7 +1077,8 @@ check_PROGRAMS+=\ tests/testSBuf \ tests/testSBufList \ tests/testConfigParser \ - tests/testStatHist + tests/testStatHist \ + tests/testVector if HAVE_FS_ROCK check_PROGRAMS += tests/testRock @@ -3825,6 +3826,21 @@ tests_testStatHist_LDADD = \ $(COMPAT_LIB) tests_testStatHist_DEPENDENCIES = $(SQUID_CPPUNIT_LA) +tests_testVector_SOURCES = \ + tests/testVector.cc \ + tests/testMain.cc \ + tests/testVector.h +nodist_tests_testVector_SOURCES = \ + $(TESTSOURCES) +tests_testVector_LDADD= \ + $(SQUID_CPPUNIT_LIBS) \ + $(COMPAT_LIB) \ + $(XTRA_LIBS) +tests_testVector_LDFLAGS = $(LIBADD_DL) +tests_testVector_DEPENDENCIES = \ + $(SQUID_CPPUNIT_LA) + + TESTS += testHeaders ## Special Universal .h dependency test script diff --git a/src/base/Makefile.am b/src/base/Makefile.am index 3591294cf8..80533ad426 100644 --- a/src/base/Makefile.am +++ b/src/base/Makefile.am @@ -23,7 +23,9 @@ libbase_la_SOURCES = \ RunnersRegistry.h \ Subscription.h \ TextException.cc \ - TextException.h + TextException.h \ + Vector.cc \ + Vector.h EXTRA_PROGRAMS = \ testCharacterSet diff --git a/src/base/Vector.cc b/src/base/Vector.cc new file mode 100644 index 0000000000..afc420aec9 --- /dev/null +++ b/src/base/Vector.cc @@ -0,0 +1,48 @@ +/* + * AUTHOR: Alex Rousskov + * + * 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. + * + */ + +/* + * Array is an array of (void*) items with unlimited capacity + * + * Array grows when arrayAppend() is called and no space is left + * Currently, array does not have an interface for deleting an item because + * we do not need such an interface yet. + */ + +#include "squid.h" +#include "base/Vector.h" + +#if HAVE_ASSERT_H +#include +#endif +#if HAVE_STRING_H +#include +#endif diff --git a/src/base/Vector.h b/src/base/Vector.h new file mode 100644 index 0000000000..05d58f1281 --- /dev/null +++ b/src/base/Vector.h @@ -0,0 +1,471 @@ +/* + * AUTHOR: Alex Rousskov + * + * 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_ARRAY_H +#define SQUID_ARRAY_H + +/** + \todo remove this after replacing with STL + */ + +#include "fatal.h" +#include "util.h" + +/* users of this template also need assert() */ +#include "compat/assert.h" + +/* iterator support */ +#include + +template +class VectorIteratorBase +{ +public: + typedef typename C::value_type value_type; + typedef std::forward_iterator_tag iterator_category; + typedef typename C::pointer pointer; + typedef typename C::reference reference; + typedef typename C::difference_type difference_type; + + VectorIteratorBase(); + VectorIteratorBase(C &); + VectorIteratorBase(size_t, C &); + VectorIteratorBase & operator =(VectorIteratorBase const &); + bool operator != (VectorIteratorBase const &rhs) const; + bool operator == (VectorIteratorBase const &rhs) const; + VectorIteratorBase & operator ++(); + VectorIteratorBase operator ++(int); + typename C::value_type & operator *() const { + return theVector->items[pos]; + } + + typename C::value_type * operator -> () const { + return &theVector->items[pos]; + } + + ssize_t operator - (VectorIteratorBase const &rhs) const; + bool incrementable() const; + +private: + size_t pos; + C * theVector; +}; + +template +class Vector +{ +public: + typedef E value_type; + typedef E* pointer; + typedef E& reference; + typedef VectorIteratorBase > iterator; + typedef VectorIteratorBase const> const_iterator; + typedef ptrdiff_t difference_type; + friend class VectorIteratorBase >; + friend class VectorIteratorBase const>; + void *operator new (size_t); + void operator delete (void *); + + Vector(); + ~Vector(); + Vector(Vector const &); + Vector &operator = (Vector const &); + void clear(); + void reserve (size_t capacity); + void push_back (E); + + void insert (E); + const E &front() const; + E &front(); + E &back(); + void pop_back(); + E shift(); // aka pop_front + void prune(E); + void preAppend(int app_count); + inline bool empty() const; + inline size_t size() const; + iterator begin(); + const_iterator begin () const; + iterator end(); + const_iterator end () const; + E& at(unsigned i); + const E& at(unsigned i) const; + inline E& operator [] (unsigned i); + inline const E& operator [] (unsigned i) const; + E* data() const { return items; } + +protected: + size_t capacity; + size_t count; + E *items; +}; + +template +void * +Vector::operator new(size_t size) +{ + return xmalloc(size); +} + +template +void +Vector::operator delete (void *address) +{ + xfree (address); +} + +template +Vector::Vector() : capacity (0), count(0), items (NULL) +{} + +template +Vector::~Vector() +{ + clear(); +} + +template +void +Vector::clear() +{ + /* could also warn if some objects are left */ + delete[] items; + items = NULL; + capacity = 0; + count = 0; +} + +/* grows internal buffer to satisfy required minimal capacity */ +template +void +Vector::reserve(size_t min_capacity) +{ + const int min_delta = 16; + int delta; + + if (capacity >= min_capacity) + return; + + delta = min_capacity; + + /* make delta a multiple of min_delta */ + delta += min_delta - 1; + + delta /= min_delta; + + delta *= min_delta; + + /* actual grow */ + if (delta < 0) + delta = min_capacity - capacity; + + E*newitems = new E[capacity + delta]; + + for (size_t counter = 0; counter < size(); ++counter) { + newitems[counter] = items[counter]; + } + + capacity += delta; + delete[]items; + items = newitems; +} + +template +void +Vector::push_back(E obj) +{ + if (size() >= capacity) + reserve (size() + 1); + + items[count++] = obj; +} + +template +void +Vector::insert(E obj) +{ + if (size() >= capacity) + reserve (size() + 1); + + int i; + + for (i = count; i > 0; i--) + items[i] = items[i - 1]; + + items[i] = obj; + + count += 1; +} + +template +E +Vector::shift() +{ + assert (size()); + value_type result = items[0]; + + for (unsigned int i = 1; i < count; i++) + items[i-1] = items[i]; + + count--; + + /*reset the last (unused) element...*/ + items[count] = value_type(); + + return result; +} + +template +void +Vector::pop_back() +{ + assert (size()); + --count; + items[count] = value_type(); +} + +template +E & +Vector::back() +{ + assert (size()); + return items[size() - 1]; +} + +template +const E & +Vector::front() const +{ + assert (size()); + return items[0]; +} + +template +E & +Vector::front() +{ + assert (size()); + return items[0]; +} + +template +void +Vector::prune(E item) +{ + unsigned int n = 0; + for (unsigned int i = 0; i < count; i++) { + if (items[i] != item) { + if (i != n) + items[n] = items[i]; + n++; + } + } + + count = n; +} + +/* if you are going to append a known and large number of items, call this first */ +template +void +Vector::preAppend(int app_count) +{ + if (size() + app_count > capacity) + reserve(size() + app_count); +} + +template +Vector::Vector (Vector const &rhs) +{ + items = NULL; + capacity = 0; + count = 0; + reserve (rhs.size()); + + for (size_t counter = 0; counter < rhs.size(); ++counter) + push_back (rhs.items[counter]); +} + +template +Vector & +Vector::operator = (Vector const &old) +{ + clear(); + reserve (old.size()); + + for (size_t counter = 0; counter < old.size(); ++counter) + push_back (old.items[counter]); + + return *this; +} + +template +bool +Vector::empty() const +{ + return size() == 0; +} + +template +size_t +Vector::size() const +{ + return count; +} + +template +typename Vector::iterator +Vector::begin() +{ + return iterator (0, *this); +} + +template +typename Vector::iterator +Vector::end() +{ + return iterator(size(), *this); +} + +template +typename Vector::const_iterator +Vector::begin() const +{ + return const_iterator (0, *this); +} + +template +typename Vector::const_iterator +Vector::end() const +{ + return const_iterator(size(), *this); +} + +template +E & +Vector::at(unsigned i) +{ + assert (size() > i); + return operator[](i); +} + +template +const E & +Vector::at(unsigned i) const +{ + assert (size() > i); + return operator[](i); +} + +template +E & +Vector::operator [] (unsigned i) +{ + return items[i]; +} + +template +const E & +Vector::operator [] (unsigned i) const +{ + return items[i]; +} + +template +VectorIteratorBase::VectorIteratorBase() : pos(0), theVector(NULL) +{} + +template +VectorIteratorBase::VectorIteratorBase(C &container) : pos(container.begin()), theVector(&container) +{} + +template +VectorIteratorBase::VectorIteratorBase(size_t aPos, C &container) : pos(aPos), theVector(&container) {} + +template +bool VectorIteratorBase:: operator != (VectorIteratorBase const &rhs) const +{ + assert (theVector); + return pos != rhs.pos; +} + +template +bool VectorIteratorBase:: operator == (VectorIteratorBase const &rhs) const +{ + assert (theVector); + return pos == rhs.pos; +} + +template +bool +VectorIteratorBase::incrementable() const +{ + assert (theVector); + return pos != theVector->size(); +} + +template +VectorIteratorBase & VectorIteratorBase:: operator ++() +{ + assert (theVector); + + if (!incrementable()) + fatal ("domain error"); + + ++pos; + + return *this; +} + +template +VectorIteratorBase VectorIteratorBase:: operator ++(int) +{ + VectorIteratorBase result(*this); + ++*this; + return result; +} + +template +VectorIteratorBase& +VectorIteratorBase::operator =(VectorIteratorBase const &old) +{ + pos = old.pos; + theVector = old.theVector; + return *this; +} + +template +ssize_t +VectorIteratorBase::operator - (VectorIteratorBase const &rhs) const +{ + assert(theVector == rhs.theVector); + return pos - rhs.pos; +} + +#endif /* SQUID_ARRAY_H */ diff --git a/src/cbdata.cc b/src/cbdata.cc index ae2827bf1d..a0cf24acb3 100644 --- a/src/cbdata.cc +++ b/src/cbdata.cc @@ -50,13 +50,12 @@ #include "cbdata.h" #include "mgr/Registration.h" #include "Store.h" +#if USE_CBDATA_DEBUG +#include "Stack.h" +#endif #include "Generic.h" #include -#if USE_CBDATA_DEBUG -#include -#include -#endif #if WITH_VALGRIND #define HASHED_CBDATA 1 @@ -123,7 +122,7 @@ public: dlink_node link; const char *file; int line; - std::vector calls; // used as a stack with random access operator + Stack calls; #endif /* cookie used while debugging */ @@ -208,11 +207,10 @@ cbdata_hash(const void *p, unsigned int mod) cbdata::~cbdata() { #if USE_CBDATA_DEBUG + CBDataCall *aCall; - while (!calls.empty()) { - delete calls.back(); - calls.pop_back(); - } + while ((aCall = calls.pop())) + delete aCall; #endif @@ -316,7 +314,7 @@ cbdataInternalAlloc(cbdata_type type) c->file = file; c->line = line; - c->calls = std::vector (); + c->calls = Stack (); c->addHistory("Alloc", file, line); dlinkAdd(c, &c->link, &cbdataEntries); debugs(45, 3, "cbdataAlloc: " << p << " " << file << ":" << line); @@ -614,8 +612,8 @@ CBDATA_CLASS_INIT(generic_cbdata); struct CBDataCallDumper : public unary_function { CBDataCallDumper (StoreEntry *anEntry):where(anEntry) {} - void operator()(CBDataCall * const &x) { - storeAppendPrintf(where, "%s\t%s\t%d\n", x->label, x->file, x->line); + void operator()(CBDataCall const &x) { + storeAppendPrintf(where, "%s\t%s\t%d\n", x.label, x.file, x.line); } StoreEntry *where; @@ -628,7 +626,7 @@ struct CBDataHistoryDumper : public CBDataDumper { CBDataDumper::operator()(x); storeAppendPrintf(where, "\n"); storeAppendPrintf(where, "Action\tFile\tLine\n"); - std::for_each (x.calls.begin(), x.calls.end(), callDumper); + for_each (x.calls,callDumper); storeAppendPrintf(where, "\n"); } diff --git a/src/store.cc b/src/store.cc index ebea92f716..b46504f8b4 100644 --- a/src/store.cc +++ b/src/store.cc @@ -51,6 +51,7 @@ #include "RequestFlags.h" #include "SquidConfig.h" #include "SquidTime.h" +#include "Stack.h" #include "StatCounters.h" #include "stmem.h" #include "Store.h" @@ -71,7 +72,6 @@ #endif #include -#include #define REBUILD_TIMESTAMP_DELTA_MAX 2 @@ -124,7 +124,7 @@ static EVH storeLateRelease; /* * local variables */ -static std::stack LateReleaseStack; +static Stack LateReleaseStack; MemAllocator *StoreEntry::pool = NULL; StorePointer Store::CurrentRoot = NULL; @@ -1252,7 +1252,7 @@ StoreEntry::release() // lock the entry until rebuilding is done lock("storeLateRelease"); setReleaseFlag(); - LateReleaseStack.push(this); + LateReleaseStack.push_back(this); } else { destroyStoreEntry(static_cast(this)); // "this" is no longer valid @@ -1280,6 +1280,7 @@ static void storeLateRelease(void *unused) { StoreEntry *e; + int i; static int n = 0; if (StoreController::store_dirs_rebuilding) { @@ -1287,14 +1288,13 @@ storeLateRelease(void *unused) return; } - // TODO: this works but looks unelegant. - for (int i = 0; i < 10; ++i) { - if (LateReleaseStack.empty()) { + for (i = 0; i < 10; ++i) { + e = LateReleaseStack.empty() ? NULL : LateReleaseStack.pop(); + + if (e == NULL) { + /* done! */ debugs(20, DBG_IMPORTANT, "storeLateRelease: released " << n << " objects"); return; - } else { - e = LateReleaseStack.top(); - LateReleaseStack.pop(); } e->unlock("storeLateRelease"); diff --git a/src/tests/testVector.cc b/src/tests/testVector.cc new file mode 100644 index 0000000000..725700777d --- /dev/null +++ b/src/tests/testVector.cc @@ -0,0 +1,19 @@ +#define SQUID_UNIT_TEST 1 +#include "squid.h" +#include "base/Vector.h" +#include "tests/testVector.h" + +#include + +CPPUNIT_TEST_SUITE_REGISTRATION( testVector ); + +void testVector::all() +{ + CPPUNIT_ASSERT_EQUAL(1 , 1); + Vector aArray; + CPPUNIT_ASSERT_EQUAL(static_cast(0), aArray.size()); + aArray.push_back(2); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aArray.size()); + CPPUNIT_ASSERT_EQUAL(2, aArray.back()); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aArray.size()); +} diff --git a/src/tests/testVector.h b/src/tests/testVector.h new file mode 100644 index 0000000000..f1606db217 --- /dev/null +++ b/src/tests/testVector.h @@ -0,0 +1,24 @@ +#ifndef SQUID_SRC_TESTS_TESTVECTOR_H +#define SQUID_SRC_TESTS_TESTVECTOR_H + +#include + +/* + * A test case that is designed to produce + * example errors and failures + * + */ + +class testVector : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testVector ); + CPPUNIT_TEST( all ); + CPPUNIT_TEST_SUITE_END(); + +public: + +protected: + void all(); +}; + +#endif diff --git a/test-suite/Makefile.am b/test-suite/Makefile.am index 6aeb5187d4..010a8bb4fb 100644 --- a/test-suite/Makefile.am +++ b/test-suite/Makefile.am @@ -31,6 +31,7 @@ endif TESTS += debug \ syntheticoperators \ VirtualDeleteOperator \ + StackTest \ splay\ MemPoolTest\ mem_node_test\ @@ -45,6 +46,7 @@ check_PROGRAMS += debug \ mem_node_test\ mem_hdr_test \ splay \ + StackTest \ syntheticoperators \ VirtualDeleteOperator @@ -87,6 +89,8 @@ MemPoolTest_SOURCES = MemPoolTest.cc splay_SOURCES = splay.cc +StackTest_SOURCES = StackTest.cc $(DEBUG_SOURCE) + syntheticoperators_SOURCES = syntheticoperators.cc $(DEBUG_SOURCE) VirtualDeleteOperator_SOURCES = VirtualDeleteOperator.cc $(DEBUG_SOURCE) diff --git a/test-suite/StackTest.cc b/test-suite/StackTest.cc new file mode 100644 index 0000000000..377d899a82 --- /dev/null +++ b/test-suite/StackTest.cc @@ -0,0 +1,56 @@ + +/* + * DEBUG: section 19 Store Memory Primitives + * AUTHOR: Robert Collins + * + * 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. + * + * Copyright (c) 2003 Robert Collins + */ + +#include "squid.h" +#include "Stack.h" + +int +main(int argc, char **argv) +{ + Stack aStack; + assert (aStack.size() == 0); + aStack.push_back(2); + assert (aStack.size() == 1); + assert (aStack.top() == 2); + assert (aStack.pop() == 2); + assert (aStack.size() == 0); + Stack<> oldStack; + assert (oldStack.size() == 0); + oldStack.push_back(&aStack); + assert (oldStack.size() == 1); + assert (oldStack.top() == &aStack); + assert (oldStack.pop() == &aStack); + assert (oldStack.size() == 0); + return 0; +}