From: robertc <> Date: Sat, 8 Feb 2003 08:45:46 +0000 (+0000) Subject: Summary: Merge delay class 4 performance enhancements. X-Git-Tag: SQUID_3_0_PRE1~382 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=29b17d63a524ac9855a7d286c6313a82050f485a;p=thirdparty%2Fsquid.git Summary: Merge delay class 4 performance enhancements. Keywords: Patches applied: * robertc@squid-cache.org--squid/squid--delay-class-4--3.0--patch-31 Convert ACL.h listed types to SplayNode. * robertc@squid-cache.org--squid/squid--delay-class-4--3.0--patch-30 Make splay trees typesafe, and use in DelayUser class. * robertc@squid-cache.org--squid/squid--delay-class-4--3.0--patch-29 Separate splay usage from global includes. --- diff --git a/include/MemPool.h b/include/MemPool.h index 75f347fbc0..0198db30cd 100644 --- a/include/MemPool.h +++ b/include/MemPool.h @@ -5,7 +5,13 @@ #include "config.h" #include "Array.h" #include "util.h" +#ifdef __cplusplus +template +class SplayNode; +typedef SplayNode splayNode; +#else #include "splay.h" +#endif #include "memMeter.h" #if HAVE_GNUMALLOC_H diff --git a/include/splay.h b/include/splay.h index ea131fcdca..c4da3c886c 100644 --- a/include/splay.h +++ b/include/splay.h @@ -1,5 +1,5 @@ /* - * $Id: splay.h,v 1.14 2003/02/05 10:36:31 robertc Exp $ + * $Id: splay.h,v 1.15 2003/02/08 01:45:46 robertc Exp $ */ #ifndef SQUID_SPLAY_H @@ -13,42 +13,202 @@ typedef struct _splay_node { struct _splay_node *right; } splayNode; -typedef int SPLAYCMP(const void *a, const void *b); -typedef void SPLAYWALKEE(void *nodedata, void *state); -typedef void SPLAYFREE(void *); +typedef int SPLAYCMP(const void **a, const void **b); +typedef void SPLAYWALKEE(void **nodedata, void *state); SQUIDCEXTERN int splayLastResult; +/* MUST match C++ prototypes */ SQUIDCEXTERN splayNode *splay_insert(void *, splayNode *, SPLAYCMP *); -SQUIDCEXTERN splayNode *splay_splay(const void *, splayNode *, SPLAYCMP *); +SQUIDCEXTERN splayNode *splay_splay(const void **, splayNode *, SPLAYCMP *); SQUIDCEXTERN splayNode *splay_delete(const void *, splayNode *, SPLAYCMP *); -SQUIDCEXTERN void splay_destroy(splayNode *, SPLAYFREE *); SQUIDCEXTERN void splay_walk(splayNode *, SPLAYWALKEE *, void *); #else + template class SplayNode { public: typedef V Value; - Value *data; - SplayNode *left; - SplayNode *right; + typedef int SPLAYCMP(Value const &a, Value const &b); + typedef void SPLAYFREE(Value &); + typedef void SPLAYWALKEE(Value const & nodedata, void *state); + Value data; + mutable SplayNode *left; + mutable SplayNode *right; + void destroy(SPLAYFREE *); + void walk(SPLAYWALKEE *, void *callerState); + SplayNode * remove(const Value data, SPLAYCMP * compare); + SplayNode * insert(Value data, SPLAYCMP * compare); + SplayNode * splay(const Value &data, SPLAYCMP * compare) const; }; -typedef SplayNode splayNode; +typedef SplayNode splayNode; + +template +class Splay { + public: + typedef V Value; + typedef int SPLAYCMP(Value const &a, Value const &b); + Splay():head(NULL){} + mutable SplayNode * head; + Value const *find (Value const &, SPLAYCMP *compare) const; +}; -typedef int SPLAYCMP(const void *a, const void *b); -typedef void SPLAYWALKEE(void *nodedata, void *state); -typedef void SPLAYFREE(void *); SQUIDCEXTERN int splayLastResult; -SQUIDCEXTERN splayNode *splay_insert(void *, splayNode *, SPLAYCMP *); -SQUIDCEXTERN splayNode *splay_splay(const void *, splayNode *, SPLAYCMP *); -SQUIDCEXTERN splayNode *splay_delete(const void *, splayNode *, SPLAYCMP *); -SQUIDCEXTERN void splay_destroy(splayNode *, SPLAYFREE *); -SQUIDCEXTERN void splay_walk(splayNode *, SPLAYWALKEE *, void *); +SQUIDCEXTERN splayNode *splay_insert(void *, splayNode *, splayNode::SPLAYCMP *); +SQUIDCEXTERN splayNode *splay_delete(const void *, splayNode *, splayNode::SPLAYCMP *); +SQUIDCEXTERN splayNode *splay_splay(const void **, splayNode *, splayNode::SPLAYCMP *); +SQUIDCEXTERN void splay_destroy(splayNode *, splayNode::SPLAYFREE *); +SQUIDCEXTERN void splay_walk(splayNode *, splayNode::SPLAYWALKEE *, void *callerState); + +/* inline methods */ +template +void +SplayNode::walk(SPLAYWALKEE * walkee, void *state) +{ + if (this == NULL) + return; + if (left) + left->walk(walkee, state); + walkee(data, state); + if (right) + right->walk(walkee, state); +} + +template +void +SplayNode::destroy(SPLAYFREE * free_func) +{ + if (!this) + return; + if (left) + left->destroy(free_func); + if (right) + right->destroy(free_func); + free_func(data); + delete this; +} + +template +SplayNode * +SplayNode::remove(Value const data, SPLAYCMP * compare) +{ + if (this == NULL) + return NULL; + SplayNode *result = splay(data, compare); + if (splayLastResult == 0) { /* found it */ + SplayNode *newTop; + if (result->left == NULL) { + newTop = result->right; + } else { + newTop = result->left->splay(data, compare); + /* temporary */ + newTop->right = result->right; + result->right = NULL; + } + delete result; + return newTop; + } + return result; /* It wasn't there */ +} +template +SplayNode * +SplayNode::insert(Value data, SPLAYCMP * compare) +{ + /* create node to insert */ + SplayNode *newNode = new SplayNode; + newNode->data = data; + if (this == NULL) { + newNode->left = newNode->right = NULL; + return newNode; + } + + SplayNode *newTop = splay(data, compare); + if (splayLastResult < 0) { + newNode->left = newTop->left; + newNode->right = newTop; + newTop->left = NULL; + return newNode; + } else if (splayLastResult > 0) { + newNode->right = newTop->right; + newNode->left = newTop; + newTop->right = NULL; + return newNode; + } else { + /* duplicate entry */ + delete newNode; + return newTop; + } +} + +template +SplayNode * +SplayNode::splay(Value const &data, SPLAYCMP * compare) const +{ + if (this == NULL) + return NULL; + SplayNode N; + SplayNode *l; + SplayNode *r; + SplayNode *y; + N.left = N.right = NULL; + l = r = &N; + + SplayNode *top = const_cast *>(this); + for (;;) { + splayLastResult = compare(data, top->data); + if (splayLastResult < 0) { + if (top->left == NULL) + break; + if ((splayLastResult = compare(data, top->left->data)) < 0) { + y = top->left; /* rotate right */ + top->left = y->right; + y->right = top; + top = y; + if (top->left == NULL) + break; + } + r->left = top; /* link right */ + r = top; + top = top->left; + } else if (splayLastResult > 0) { + if (top->right == NULL) + break; + if ((splayLastResult = compare(data, top->right->data)) > 0) { + y = top->right; /* rotate left */ + top->right = y->left; + y->left = top; + top = y; + if (top->right == NULL) + break; + } + l->right = top; /* link left */ + l = top; + top = top->right; + } else { + break; + } + } + l->right = top->left; /* assemble */ + r->left = top->right; + top->left = N.right; + top->right = N.left; + return top; +} + +template +typename Splay::Value const * +Splay::find (Value const &value, SPLAYCMP *compare) const +{ + head = head->splay(value, compare); + if (splayLastResult != 0) + return NULL; + return &head->data; +} #endif diff --git a/lib/MemPool.c b/lib/MemPool.c index 63478c3073..628cce286f 100644 --- a/lib/MemPool.c +++ b/lib/MemPool.c @@ -1,6 +1,6 @@ /* - * $Id: MemPool.c,v 1.15 2003/01/23 00:37:01 robertc Exp $ + * $Id: MemPool.c,v 1.16 2003/02/08 01:45:47 robertc Exp $ * * DEBUG: section 63 Low Level Memory Pool Management * AUTHOR: Alex Rousskov, Andres Kroonmaa @@ -132,8 +132,8 @@ static int Pool_id_counter = 0; static MemPool *lastPool; /* local prototypes */ -static int memCompChunks(MemChunk * chunkA, MemChunk * chunkB); -static int memCompObjChunks(void *obj, MemChunk * chunk); +static SPLAYCMP memCompChunks; +static SPLAYCMP memCompObjChunks; #if !DISABLE_POOLS static MemChunk *memPoolChunkNew(MemPool * pool); #endif @@ -187,7 +187,15 @@ memPoolSetIdleLimit(size_t new_idle_limit) /* Compare chunks */ static int -memCompChunks(MemChunk * chunkA, MemChunk * chunkB) +memCompChunksSafe(MemChunk * chunkA, MemChunk * chunkB); +static int +memCompChunks(const void **chunkA, const void **chunkB) +{ + return memCompChunksSafe((MemChunk *)*chunkA, (MemChunk *)*chunkB); +} + +static int +memCompChunksSafe(MemChunk * chunkA, MemChunk * chunkB) { if (chunkA->objCache > chunkB->objCache) return 1; @@ -199,8 +207,14 @@ memCompChunks(MemChunk * chunkA, MemChunk * chunkB) /* Compare object to chunk */ /* XXX Note: this depends on lastPool */ +static int memCompObjChunksSafe(void *obj, MemChunk * chunk); static int -memCompObjChunks(void *obj, MemChunk * chunk) +memCompObjChunks(const void **obj, const void **chunk) +{ + return memCompObjChunksSafe((void *)*obj, (MemChunk *)*chunk); +} + +static int memCompObjChunksSafe(void *obj, MemChunk * chunk) { if (obj < chunk->objCache) return -1; @@ -234,7 +248,7 @@ memPoolChunkNew(MemPool * pool) pool->chunkCount++; chunk->lastref = squid_curtime; lastPool = pool; - pool->allChunks = splay_insert(chunk, pool->allChunks, (SPLAYCMP *) memCompChunks); + pool->allChunks = splay_insert(chunk, pool->allChunks, memCompChunks); return chunk; } #endif @@ -247,7 +261,7 @@ memPoolChunkDestroy(MemPool * pool, MemChunk * chunk) pool->idle -= pool->chunk_capacity; pool->chunkCount--; lastPool = pool; - pool->allChunks = splay_delete(chunk, pool->allChunks, (SPLAYCMP *) memCompChunks); + pool->allChunks = splay_delete(chunk, pool->allChunks, memCompChunks); xfree(chunk->objCache); xfree(chunk); } @@ -574,7 +588,7 @@ memPoolCleanOne(MemPool * pool, time_t maxage) while ((Free = pool->freeCache) != NULL) { lastPool = pool; - pool->allChunks = splay_splay(Free, pool->allChunks, (SPLAYCMP *) memCompObjChunks); + pool->allChunks = splay_splay((const void **)&Free, pool->allChunks, memCompObjChunks); assert(splayLastResult == 0); chunk = pool->allChunks->data; assert(chunk->inuse_count > 0); diff --git a/lib/Splay.cc b/lib/Splay.cc index a0863affd9..c53f49968d 100644 --- a/lib/Splay.cc +++ b/lib/Splay.cc @@ -1,5 +1,5 @@ /* - * $Id: Splay.cc,v 1.1 2003/02/05 10:36:40 robertc Exp $ + * $Id: Splay.cc,v 1.2 2003/02/08 01:45:47 robertc Exp $ * * based on ftp://ftp.cs.cmu.edu/user/sleator/splaying/top-down-splay.c * http://bobo.link.cs.cmu.edu/cgi-bin/splay/splay-cgi.pl @@ -23,124 +23,33 @@ int splayLastResult = 0; splayNode * -splay_insert(void *data, splayNode * top, SPLAYCMP * compare) +splay_insert(void *data, splayNode * top, splayNode::SPLAYCMP * compare) { - splayNode *newNode = new splayNode; - newNode->data = data; - if (top == NULL) { - newNode->left = newNode->right = NULL; - return newNode; - } - top = splay_splay(data, top, compare); - if (splayLastResult < 0) { - newNode->left = top->left; - newNode->right = top; - top->left = NULL; - return newNode; - } else if (splayLastResult > 0) { - newNode->right = top->right; - newNode->left = top; - top->right = NULL; - return newNode; - } else { - /* duplicate entry */ - xfree(newNode); - return top; - } + return top->insert (data, compare); } splayNode * -splay_splay(const void *data, splayNode * top, SPLAYCMP * compare) +splay_splay(const void **data, splayNode * top, splayNode::SPLAYCMP * compare) { - splayNode N; - splayNode *l; - splayNode *r; - splayNode *y; - if (top == NULL) - return top; - N.left = N.right = NULL; - l = r = &N; - - for (;;) { - splayLastResult = compare(data, top->data); - if (splayLastResult < 0) { - if (top->left == NULL) - break; - if ((splayLastResult = compare(data, top->left->data)) < 0) { - y = top->left; /* rotate right */ - top->left = y->right; - y->right = top; - top = y; - if (top->left == NULL) - break; - } - r->left = top; /* link right */ - r = top; - top = top->left; - } else if (splayLastResult > 0) { - if (top->right == NULL) - break; - if ((splayLastResult = compare(data, top->right->data)) > 0) { - y = top->right; /* rotate left */ - top->right = y->left; - y->left = top; - top = y; - if (top->right == NULL) - break; - } - l->right = top; /* link left */ - l = top; - top = top->right; - } else { - break; - } - } - l->right = top->left; /* assemble */ - r->left = top->right; - top->left = N.right; - top->right = N.left; - return top; + return top->splay((void * const)*data, compare); } splayNode * -splay_delete(const void *data, splayNode * top, SPLAYCMP * compare) +splay_delete(const void *data, splayNode * top, splayNode::SPLAYCMP * compare) { - splayNode *x; - if (top == NULL) - return NULL; - top = splay_splay(data, top, compare); - if (splayLastResult == 0) { /* found it */ - if (top->left == NULL) { - x = top->right; - } else { - x = splay_splay(data, top->left, compare); - x->right = top->right; - } - xfree(top); - return x; - } - return top; /* It wasn't there */ + return top->remove ((void * const)data, compare); } void -splay_destroy(splayNode * top, SPLAYFREE * free_func) +splay_destroy(splayNode * top, splayNode::SPLAYFREE * free_func) { - if (top->left) - splay_destroy(top->left, free_func); - if (top->right) - splay_destroy(top->right, free_func); - free_func(top->data); - xfree(top); + top->destroy(free_func); } void -splay_walk(splayNode * top, SPLAYWALKEE * walkee, void *state) +splay_walk(splayNode * top, splayNode::SPLAYWALKEE * walkee, void *state) { - if (top->left) - splay_walk(top->left, walkee, state); - walkee(top->data, state); - if (top->right) - splay_walk(top->right, walkee, state); + top->walk(walkee,state); } #ifdef DEBUG diff --git a/src/ACL.h b/src/ACL.h index ca7c0d65da..c691899822 100644 --- a/src/ACL.h +++ b/src/ACL.h @@ -1,6 +1,6 @@ /* - * $Id: ACL.h,v 1.1 2003/02/05 10:36:48 robertc Exp $ + * $Id: ACL.h,v 1.2 2003/02/08 01:45:47 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -35,7 +35,37 @@ #ifndef SQUID_ACL_H #define SQUID_ACL_H - +#include "splay.h" + +/* As ACL's get refactored, these probably need better homes */ + +#if USE_SSL +class acl_cert_data { + public: + void *operator new(size_t); + void operator delete(void *); + virtual void deleteSelf() const; + SplayNode *values; + char *attribute; + private: + static MemPool *Pool; +}; +#endif + +class acl_user_data { + public: + void *operator new(size_t); + void operator delete(void *); + virtual void deleteSelf() const; + SplayNode *names; + struct { + unsigned int case_insensitive:1; + unsigned int required:1; + } flags; + private: + static MemPool *Pool; +}; + void dump_acl_access(StoreEntry * entry, const char *name, acl_access * head); #endif /* SQUID_ACL_H */ diff --git a/src/DelayUser.cc b/src/DelayUser.cc index b94a82b178..5c8de374e9 100644 --- a/src/DelayUser.cc +++ b/src/DelayUser.cc @@ -1,6 +1,6 @@ /* - * $Id: DelayUser.cc,v 1.2 2003/02/06 09:57:36 robertc Exp $ + * $Id: DelayUser.cc,v 1.3 2003/02/08 01:45:47 robertc Exp $ * * DEBUG: section 77 Delay Pools * AUTHOR: Robert Collins @@ -69,9 +69,32 @@ DelayUser::DelayUser() DelayPools::registerForUpdates (this); } +static SplayNode::SPLAYFREE DelayUserFree; + DelayUser::~DelayUser() { DelayPools::deregisterForUpdates (this); + buckets.head->destroy (DelayUserFree); +} + +static SplayNode::SPLAYCMP DelayUserCmp; + +int +DelayUserCmp(DelayUserBucket::Pointer const &left, DelayUserBucket::Pointer const &right) +{ + /* for rate limiting, case insensitive */ + return strcasecmp(left->authUser->username(), right->authUser->username()); +} + +void +DelayUserFree(DelayUserBucket::Pointer &) +{ +} + +void +DelayUserStatsWalkee(DelayUserBucket::Pointer const ¤t, void *state) +{ + current->stats ((StoreEntry *)state); } void @@ -81,15 +104,11 @@ DelayUser::stats(StoreEntry * sentry) if (spec.restore_bps == -1) return; storeAppendPrintf(sentry, "\t\tCurrent: "); - if (!buckets.size()) { + if (!buckets.head) { storeAppendPrintf (sentry, "Not used yet.\n\n"); return; } - iterator pos = buckets.begin(); - while (pos != buckets.end()) { - (*pos)->stats(sentry); - ++pos; - } + buckets.head->walk(DelayUserStatsWalkee, sentry); storeAppendPrintf(sentry, "\n\n"); } @@ -99,14 +118,24 @@ DelayUser::dump(StoreEntry *entry) const spec.dump(entry); } +struct DelayUserUpdater +{ + DelayUserUpdater (DelaySpec &_spec, int _incr):spec(_spec),incr(_incr){}; + DelaySpec spec; + int incr; +}; +void +DelayUserUpdateWalkee(DelayUserBucket::Pointer const ¤t, void *state) +{ + DelayUserUpdater *t = (DelayUserUpdater *)state; + /* This doesn't change the value of the DelayUserBucket, so is safe */ + const_cast(current.getRaw())->theBucket.update(t->spec, t->incr); +} void DelayUser::update(int incr) { - iterator pos = buckets.begin(); - while (pos != buckets.end()) { - (*pos)->theBucket.update(spec, incr); - ++pos; - } + DelayUserUpdater updater(spec, incr); + buckets.head->walk (DelayUserUpdateWalkee, &updater); } void @@ -178,18 +207,14 @@ DelayUserBucket::stats (StoreEntry *entry) const DelayUser::Id::Id(DelayUser::Pointer aDelayUser,AuthUser *aUser) : theUser(aDelayUser) { - DelayUser::iterator pos = theUser->buckets.begin(); - while (pos != theUser->buckets.end()) { - if ((*pos)->authUser == aUser) { - theBucket = (*pos); - return; - } - ++pos; - } - theBucket = new DelayUserBucket(aUser); + DelayUserBucket::Pointer const *existing = theUser->buckets.find(theBucket, DelayUserCmp); + if (existing) { + theBucket = *existing; + return; + } theBucket->theBucket.init(theUser->spec); - theUser->buckets.push_back (theBucket); + theUser->buckets.head = theUser->buckets.head->insert (theBucket, DelayUserCmp); } DelayUser::Id::~Id() diff --git a/src/DelayUser.h b/src/DelayUser.h index c9a079049b..f539e43db9 100644 --- a/src/DelayUser.h +++ b/src/DelayUser.h @@ -1,6 +1,6 @@ /* - * $Id: DelayUser.h,v 1.1 2003/02/05 21:06:30 robertc Exp $ + * $Id: DelayUser.h,v 1.2 2003/02/08 01:45:47 robertc Exp $ * * DEBUG: section 77 Delay Pools * AUTHOR: Robert Collins @@ -47,6 +47,7 @@ #include "DelayBucket.h" #include "DelaySpec.h" #include "Array.h" +#include "splay.h" class DelayUserBucket : public RefCountable { public: @@ -90,7 +91,6 @@ private: DelayUserBucket::Pointer theBucket; }; DelaySpec spec; - Vector buckets; - typedef Vector::iterator iterator; + Splay buckets; }; #endif /* DELAYUSER_H */ diff --git a/src/acl.cc b/src/acl.cc index a599c013a8..ef840c18fc 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -1,5 +1,5 @@ /* - * $Id: acl.cc,v 1.297 2003/01/28 01:29:33 robertc Exp $ + * $Id: acl.cc,v 1.298 2003/02/08 01:45:47 robertc Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -33,6 +33,7 @@ */ #include "squid.h" +#include "ACL.h" #include "ACLChecklist.h" #include "splay.h" #include "HttpRequest.h" @@ -87,21 +88,21 @@ static wordlist *aclDumpIntlistList(intlist * data); static wordlist *aclDumpIntRangeList(intrange * data); static wordlist *aclDumpProtoList(intlist * data); static wordlist *aclDumpMethodList(intlist * data); -static SPLAYCMP aclIpAddrNetworkCompare; -static SPLAYCMP aclIpNetworkCompare; -static SPLAYCMP aclHostDomainCompare; -static SPLAYCMP aclDomainCompare; -static SPLAYWALKEE aclDumpIpListWalkee; -static SPLAYWALKEE aclDumpDomainListWalkee; -static SPLAYFREE aclFreeIpData; +static splayNode::SPLAYCMP aclIpAddrNetworkCompare; +static splayNode::SPLAYCMP aclIpNetworkCompare; +static splayNode::SPLAYCMP aclHostDomainCompare; +template int aclDomainCompare(T const &a, T const &b); +static splayNode::SPLAYWALKEE aclDumpIpListWalkee; +static splayNode::SPLAYWALKEE aclDumpDomainListWalkee; +static splayNode::SPLAYFREE aclFreeIpData; #if USE_ARP_ACL static void aclParseArpList(void *curlist); static int decode_eth(const char *asc, char *eth); static int aclMatchArp(void *dataptr, struct in_addr c); static wordlist *aclDumpArpList(void *); -static SPLAYCMP aclArpCompare; -static SPLAYWALKEE aclDumpArpListWalkee; +static splayNode::SPLAYCMP aclArpCompare; +static splayNode::SPLAYWALKEE aclDumpArpListWalkee; #endif static int aclCacheMatchAcl(dlink_list * cache, squid_acl acltype, void *data, char const *MatchParam); #if USE_SSL @@ -112,6 +113,27 @@ static wordlist *aclDumpCertList(void *data); static void aclDestroyCertList(void *data); #endif +template +inline void +xRefFree(T &thing) +{ + xfree (thing); +} + +template +inline int +splaystrcmp (T&l, T&r) +{ + return strcmp ((char *)l,(char *)r); +} + +template +inline int +splaystrcasecmp (T&l, T&r) +{ + return strcasecmp ((char *)l,(char *)r); +} + static squid_acl aclStrToType(const char *s) { @@ -640,12 +662,12 @@ aclParseUserList(void **current) { char *t = NULL; acl_user_data *data; - splayNode *Top = NULL; + SplayNode *Top = NULL; debug(28, 2) ("aclParseUserList: parsing user list\n"); if (*current == NULL) { debug(28, 3) ("aclParseUserList: current is null. Creating\n"); - *current = memAllocate(MEM_ACL_USER_DATA); + *current = new acl_user_data; } data = (acl_user_data*)*current; Top = data->names; @@ -660,7 +682,7 @@ aclParseUserList(void **current) } else { if (data->flags.case_insensitive) Tolower(t); - Top = splay_insert(xstrdup(t), Top, (SPLAYCMP *) strcmp); + Top = Top->insert(xstrdup(t), splaystrcmp); } } debug(28, 3) ("aclParseUserList: Case-insensitive-switch is %d\n", @@ -672,7 +694,7 @@ aclParseUserList(void **current) debug(28, 6) ("aclParseUserList: Got token: %s\n", t); if (data->flags.case_insensitive) Tolower(t); - Top = splay_insert(xstrdup(t), Top, (SPLAYCMP *) strcmp); + Top = Top->insert(xstrdup(t), splaystrcmp); } data->names = Top; } @@ -698,7 +720,7 @@ static void aclParseCertList(void *curlist) { acl_cert_data **datap = (acl_cert_data **)curlist; - splayNode **Top; + SplayNode **Top; char *t; char *attribute = strtokFile(); if (!attribute) @@ -707,12 +729,12 @@ aclParseCertList(void *curlist) if (strcasecmp((*datap)->attribute, attribute) != 0) self_destruct(); } else { - *datap = (acl_cert_data *)memAllocate(MEM_ACL_CERT_DATA); + *datap = new acl_cert_data; (*datap)->attribute = xstrdup(attribute); } Top = &(*datap)->values; while ((t = strtokFile())) { - *Top = splay_insert(xstrdup(t), *Top, aclDomainCompare); + *Top = (*Top)->insert(xstrdup(t), aclDomainCompare); } } @@ -728,7 +750,7 @@ aclMatchUserCert(void *data, ACLChecklist * checklist) value = sslGetUserAttribute(ssl, cert_data->attribute); if (!value) return 0; - cert_data->values = splay_splay(value, cert_data->values, (SPLAYCMP *) strcmp); + cert_data->values = cert_data->values->splay(const_cast(value), splaystrcmp); return !splayLastResult; } @@ -744,7 +766,7 @@ aclMatchCACert(void *data, ACLChecklist * checklist) value = sslGetCAAttribute(ssl, cert_data->attribute); if (!value) return 0; - cert_data->values = splay_splay(value, cert_data->values, (SPLAYCMP *) strcmp); + cert_data->values = cert_data->values->splay(const_cast(value), splaystrcmp); return !splayLastResult; } @@ -754,16 +776,16 @@ aclDestroyCertList(void *curlist) acl_cert_data **datap = (acl_cert_data **)curlist; if (!*datap) return; - splay_destroy((*datap)->values, xfree); - memFree(*datap, MEM_ACL_CERT_DATA); + (*datap)->values->destroy(xRefFree); + delete *datap; *datap = NULL; } static void -aclDumpCertListWalkee(void *node_data, void *outlist) +aclDumpCertListWalkee(char *const&node_data, void *outlist) { wordlist **wl = (wordlist **)outlist; - wordlistAdd(wl, (const char *)node_data); + wordlistAdd(wl, node_data); } static wordlist * @@ -772,8 +794,7 @@ aclDumpCertList(void *curlist) acl_cert_data *data = (acl_cert_data *)curlist; wordlist *wl = NULL; wordlistAdd(&wl, data->attribute); - if (data->values) - splay_walk(data->values, aclDumpCertListWalkee, &wl); + data->values->walk(aclDumpCertListWalkee, &wl); return wl; } #endif @@ -1131,7 +1152,8 @@ aclMatchIp(void *dataptr, struct in_addr c) x.addr2 = any_addr; x.mask = no_addr; x.next = NULL; - *Top = splay_splay(&x, *Top, aclIpAddrNetworkCompare); + const void *X = &x; + *Top = splay_splay(&X, *Top, aclIpAddrNetworkCompare); debug(28, 3) ("aclMatchIp: '%s' %s\n", inet_ntoa(c), splayLastResult ? "NOT found" : "found"); return !splayLastResult; @@ -1148,7 +1170,8 @@ aclMatchDomainList(void *dataptr, const char *host) if (host == NULL) return 0; debug(28, 3) ("aclMatchDomainList: checking '%s'\n", host); - *Top = splay_splay(host, *Top, aclHostDomainCompare); + const void * __host = host; + *Top = splay_splay(&__host, *Top, aclHostDomainCompare); debug(28, 3) ("aclMatchDomainList: '%s' %s\n", host, splayLastResult ? "NOT found" : "found"); return !splayLastResult; @@ -1185,7 +1208,7 @@ static int aclMatchUser(void *proxyauth_acl, char const *user) { acl_user_data *data = (acl_user_data *) proxyauth_acl; - splayNode *Top = data->names; + SplayNode *Top = data->names; debug(28, 7) ("aclMatchUser: user is %s, case_insensitive is %d\n", user, data->flags.case_insensitive); @@ -1200,10 +1223,10 @@ aclMatchUser(void *proxyauth_acl, char const *user) return 1; } if (data->flags.case_insensitive) - Top = splay_splay(user, Top, (SPLAYCMP *) strcasecmp); + Top = Top->splay((char *)user, splaystrcasecmp); else - Top = splay_splay(user, Top, (SPLAYCMP *) strcmp); - /* Top=splay_splay(user,Top,(SPLAYCMP *)dumping_strcmp); */ + Top = Top->splay((char *)user, splaystrcmp); + /* Top=splay_splay(user,Top,(splayNode::SPLAYCMP *)dumping_strcmp); */ debug(28, 7) ("aclMatchUser: returning %d,Top is %p, Top->data is %s\n", !splayLastResult, Top, (char *) (Top ? Top->data : "Unavailable")); data->names = Top; @@ -2212,7 +2235,7 @@ aclDestroyRegexList(relist * data) } static void -aclFreeIpData(void *p) +aclFreeIpData(void * &p) { memFree(p, MEM_ACL_IP_DATA); } @@ -2222,8 +2245,8 @@ aclFreeUserData(void *data) { acl_user_data *d = (acl_user_data *)data; if (d->names) - splay_destroy(d->names, xfree); - memFree(d, MEM_ACL_USER_DATA); + d->names->destroy(xRefFree); + delete d; } @@ -2246,7 +2269,7 @@ aclDestroyAcls(acl ** head) #endif case ACL_DST_DOMAIN: case ACL_SRC_DOMAIN: - splay_destroy((splayNode *)a->data, xfree); + splay_destroy((splayNode *)a->data, xRefFree); break; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: @@ -2379,20 +2402,20 @@ aclDestroyIntRange(intrange * list) /* compare two domains */ -static int -aclDomainCompare(const void *a, const void *b) +template +int +aclDomainCompare(T const &a, T const &b) { - const char *d1; - const char *d2; + char * const d1 = (char *const)b; + char * const d2 = (char *const )a; int ret; - d1 = (const char *)b; - d2 = (const char *)a; ret = aclHostDomainCompare(d1, d2); if (ret != 0) { - d1 = (const char *)a; - d2 = (const char *)b; - ret = aclHostDomainCompare(d1, d2); + char *const d3 = d2; + char *const d4 = d1; + ret = aclHostDomainCompare(d3, d4); } + /* FIXME this warning may display d1 and d2 when it should display d3 and d4 */ if (ret == 0) { debug(28, 0) ("WARNING: '%s' is a subdomain of '%s'\n", d1, d2); debug(28, 0) ("WARNING: because of this '%s' is ignored to keep splay tree searching predictable\n", (char *) a); @@ -2404,7 +2427,7 @@ aclDomainCompare(const void *a, const void *b) /* compare a host and a domain */ static int -aclHostDomainCompare(const void *a, const void *b) +aclHostDomainCompare( void *const &a, void * const &b) { const char *h = (const char *)a; const char *d = (const char *)b; @@ -2441,7 +2464,7 @@ aclIpDataToStr(const acl_ip_data * ip, char *buf, int len) * bits with the network subnet mask. */ static int -aclIpNetworkCompare2(const acl_ip_data * p, const acl_ip_data * q) +aclIpNetworkCompare2(acl_ip_data * const &p, acl_ip_data * const &q) { struct in_addr A = p->addr1; const struct in_addr B = q->addr1; @@ -2473,18 +2496,16 @@ aclIpNetworkCompare2(const acl_ip_data * p, const acl_ip_data * q) * sorting algorithm. Much like aclDomainCompare. */ static int -aclIpNetworkCompare(const void *a, const void *b) +aclIpNetworkCompare(void * const & a, void * const &b) { - const acl_ip_data *n1; - const acl_ip_data *n2; + acl_ip_data * const n1 = (acl_ip_data *const)b; + acl_ip_data * const n2 = (acl_ip_data *const)a; int ret; - n1 = (const acl_ip_data *)b; - n2 = (const acl_ip_data *)a; ret = aclIpNetworkCompare2(n1, n2); if (ret != 0) { - n1 = (const acl_ip_data *)a; - n2 = (const acl_ip_data *)b; - ret = aclIpNetworkCompare2(n1, n2); + acl_ip_data * const n3 = n2; + acl_ip_data * const n4 = n1; + ret = aclIpNetworkCompare2(n3, n4); } if (ret == 0) { char buf_n1[60]; @@ -2493,6 +2514,7 @@ aclIpNetworkCompare(const void *a, const void *b) aclIpDataToStr(n1, buf_n1, 60); aclIpDataToStr(n2, buf_n2, 60); aclIpDataToStr((acl_ip_data *) a, buf_a, 60); + /* TODO: this warning may display the wrong way around */ debug(28, 0) ("WARNING: '%s' is a subnetwork of " "'%s'\n", buf_n1, buf_n2); debug(28, 0) ("WARNING: because of this '%s' is ignored " @@ -2511,13 +2533,13 @@ aclIpNetworkCompare(const void *a, const void *b) * function is called via aclMatchIp() and the splay library. */ static int -aclIpAddrNetworkCompare(const void *a, const void *b) +aclIpAddrNetworkCompare(void *const &a, void * const &b) { - return aclIpNetworkCompare2((const acl_ip_data *)a, (const acl_ip_data *)b); + return aclIpNetworkCompare2((acl_ip_data * const)a, (acl_ip_data * const)b); } static void -aclDumpUserListWalkee(void *node_data, void *outlist) +aclDumpUserListWalkee(char * const & node_data, void *outlist) { /* outlist is really a wordlist ** */ wordlistAdd((wordlist **)outlist, (char const *)node_data); @@ -2536,12 +2558,12 @@ aclDumpUserList(acl_user_data * data) if (data->flags.required) wordlistAdd(&wl, "REQUIRED"); else if (data->names) - splay_walk(data->names, aclDumpUserListWalkee, &wl); + data->names->walk(aclDumpUserListWalkee, &wl); return wl; } static void -aclDumpIpListWalkee(void *node, void *state) +aclDumpIpListWalkee(void * const & node, void *state) { acl_ip_data *ip = (acl_ip_data *)node; MemBuf mb; @@ -2565,7 +2587,7 @@ aclDumpIpList(void *data) } static void -aclDumpDomainListWalkee(void *node, void *state) +aclDumpDomainListWalkee(void * const &node, void *state) { char *domain = (char *)node; wordlistAdd((wordlist **)state, domain); @@ -3023,7 +3045,7 @@ aclMatchArp(void *dataptr, struct in_addr c) } static int -aclArpCompare(const void *a, const void *b) +aclArpCompare(void * const &a, void * const &b) { #if defined(_SQUID_LINUX_) const unsigned short *d1 = (const unsigned short *)a; @@ -3105,7 +3127,7 @@ checkARP(u_long ip, char *eth) #endif static void -aclDumpArpListWalkee(void *node, void *state) +aclDumpArpListWalkee(void * &node, void *state) { acl_arp_data *arp = (acl_arp_data *)node; static char buf[24]; @@ -3125,3 +3147,53 @@ aclDumpArpList(void *data) /* ==== END ARP ACL SUPPORT =============================================== */ #endif /* USE_ARP_ACL */ + +/* to be split into separate files in the future */ + +MemPool *acl_user_data::Pool(NULL); +void * +acl_user_data::operator new (size_t byteCount) +{ + /* derived classes with different sizes must implement their own new */ + assert (byteCount == sizeof (acl_user_data)); + if (!Pool) + Pool = memPoolCreate("acl_user_data", sizeof (acl_user_data)); + return memPoolAlloc(Pool); +} + +void +acl_user_data::operator delete (void *address) +{ + memPoolFree (Pool, address); +} + +void +acl_user_data::deleteSelf() const +{ + delete this; +} + +#if USE_SSL +MemPool *acl_cert_data::Pool(NULL); +void * +acl_cert_data::operator new (size_t byteCount) +{ + /* derived classes with different sizes must implement their own new */ + assert (byteCount == sizeof (acl_cert_data)); + if (!Pool) + Pool = memPoolCreate("acl_cert_data", sizeof (acl_cert_data)); + return memPoolAlloc(Pool); +} + +void +acl_cert_data::operator delete (void *address) +{ + memPoolFree (Pool, address); +} + +void +acl_cert_data::deleteSelf() const +{ + delete this; +} +#endif /* USE_SSL */ diff --git a/src/enums.h b/src/enums.h index 5fdeb4f95a..781bff123d 100644 --- a/src/enums.h +++ b/src/enums.h @@ -1,6 +1,6 @@ /* - * $Id: enums.h,v 1.221 2003/01/28 01:29:34 robertc Exp $ + * $Id: enums.h,v 1.222 2003/02/08 01:45:47 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -590,7 +590,6 @@ typedef enum { MEM_ACL_LIST, MEM_ACL_NAME_LIST, MEM_ACL_PROXY_AUTH_MATCH, - MEM_ACL_USER_DATA, MEM_ACL_TIME_DATA, #if USE_CACHE_DIGESTS MEM_CACHE_DIGEST, @@ -622,9 +621,6 @@ typedef enum { #endif MEM_EVENT, MEM_SWAP_LOG_DATA, -#if USE_SSL - MEM_ACL_CERT_DATA, -#endif MEM_MAX } mem_type; diff --git a/src/mem.cc b/src/mem.cc index 8706bc760a..3dc5e65608 100644 --- a/src/mem.cc +++ b/src/mem.cc @@ -1,6 +1,6 @@ /* - * $Id: mem.cc,v 1.70 2003/01/23 00:37:23 robertc Exp $ + * $Id: mem.cc,v 1.71 2003/02/08 01:45:47 robertc Exp $ * * DEBUG: section 13 High Level Memory Pool Management * AUTHOR: Harvest Derived @@ -351,14 +351,9 @@ Mem::Init(void) memDataInit(MEM_ACL_IP_DATA, "acl_ip_data", sizeof(acl_ip_data), 0); memDataInit(MEM_ACL_LIST, "acl_list", sizeof(acl_list), 0); memDataInit(MEM_ACL_NAME_LIST, "acl_name_list", sizeof(acl_name_list), 0); -#if USE_SSL - memDataInit(MEM_ACL_CERT_DATA, "acl_cert_data", sizeof(acl_cert_data), 0); -#endif memDataInit(MEM_ACL_TIME_DATA, "acl_time_data", sizeof(acl_time_data), 0); memDataInit(MEM_ACL_PROXY_AUTH_MATCH, "acl_proxy_auth_match_cache", sizeof(acl_proxy_auth_match_cache), 0); - memDataInit(MEM_ACL_USER_DATA, "acl_user_data", - sizeof(acl_user_data), 0); #if USE_CACHE_DIGESTS memDataInit(MEM_CACHE_DIGEST, "CacheDigest", sizeof(CacheDigest), 0); #endif diff --git a/src/structs.h b/src/structs.h index 9c18dccdbe..bea093cdb0 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.446 2003/02/05 10:36:55 robertc Exp $ + * $Id: structs.h,v 1.447 2003/02/08 01:45:50 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -35,7 +35,6 @@ #define SQUID_STRUCTS_H #include "config.h" -#include "splay.h" struct _dlink_node { void *data; @@ -48,21 +47,6 @@ struct _dlink_list { dlink_node *tail; }; -#if USE_SSL -struct _acl_cert_data { - splayNode *values; - char *attribute; -}; -#endif - -struct _acl_user_data { - splayNode *names; - struct { - unsigned int case_insensitive:1; - unsigned int required:1; - } flags; -}; - struct _acl_user_ip_data { size_t max; struct { diff --git a/src/typedefs.h b/src/typedefs.h index 67fc585640..e34959e0cd 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.148 2003/02/05 10:36:56 robertc Exp $ + * $Id: typedefs.h,v 1.149 2003/02/08 01:45:51 robertc Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -64,10 +64,6 @@ typedef struct AuthUserIP auth_user_ip_t; typedef struct _acl_proxy_auth_match_cache acl_proxy_auth_match_cache; typedef struct _authscheme_entry authscheme_entry_t; typedef struct _authScheme authScheme; -#if USE_SSL -typedef struct _acl_cert_data acl_cert_data; -#endif -typedef struct _acl_user_data acl_user_data; typedef struct _acl_user_ip_data acl_user_ip_data; typedef struct _acl_arp_data acl_arp_data; typedef struct _acl_snmp_comm acl_snmp_comm; diff --git a/test-suite/splay.cc b/test-suite/splay.cc index c1db482132..324fc80a3b 100644 --- a/test-suite/splay.cc +++ b/test-suite/splay.cc @@ -1,5 +1,5 @@ /* - * $Id: splay.cc,v 1.1 2003/02/05 10:37:14 robertc Exp $ + * $Id: splay.cc,v 1.2 2003/02/08 01:45:51 robertc Exp $ * * based on ftp://ftp.cs.cmu.edu/user/sleator/splaying/top-down-splay.c * http://bobo.link.cs.cmu.edu/cgi-bin/splay/splay-cgi.pl @@ -25,33 +25,114 @@ typedef struct { } intnode; int -compareint(void const *a, void const *n) +compareintvoid(void * const &a, void * const &n) { intnode *A = (intnode *)a; intnode *B = (intnode *)n; - //((splayNode *)n)->data; return A->i - B->i; } +int +compareint(intnode * const &a, intnode * const &b) +{ + return a->i - b->i; +} + void -printint(void *a, void *state) +printintvoid(void * const &a, void *state) { intnode *A = (intnode *)a; printf("%d\n", A->i); } +void +printint (intnode * const &a, void *state) +{ + printf("%d\n",a->i); +} + +void +destintvoid(void * &data) +{ + intnode *i = (intnode *)data; + xfree (i); +} + +void +destint(intnode * &data) +{ + delete data; +} + +int +compareintref(intnode const &a, intnode const &b) +{ + return a.i - b.i; +} + +void +printintref (intnode const &a, void *unused) +{ + printf("%d\n",a.i); +} + +void +destintref (intnode &) +{ +} + int main(int argc, char *argv[]) { int i; intnode *I; + /* test void * splay containers */ splayNode *top = NULL; srandom(time(NULL)); for (i = 0; i < 100; i++) { I = (intnode *)xcalloc(sizeof(intnode), 1); I->i = random(); - top = splay_insert(I, top, compareint); + top = splay_insert(I, top, compareintvoid); + } + splay_walk(top, printintvoid, NULL); + + top->walk(printintvoid, NULL); + top->destroy(destintvoid); + /* check we don't segfault on NULL splay calls */ + top = NULL; + top->splay(NULL, compareintvoid); + + /* test typesafe splay containers */ + { + /* intnode* */ + SplayNode *safeTop = NULL; + for (i = 0; i < 100; i++) { + I = new intnode; + I->i = random(); + safeTop = safeTop->insert(I, compareint); + } + safeTop->walk(printint, NULL); + + safeTop->destroy(destint); + /* check we don't segfault on NULL splay calls */ + safeTop = NULL; + safeTop->splay(NULL, compareint); + } + { + /* intnode */ + SplayNode *safeTop = NULL; + for (i = 0; i < 100; i++) { + intnode I; + I.i = random(); + safeTop = safeTop->insert(I, compareintref); } - splay_walk(top, printint, NULL); + safeTop->walk(printintref, NULL); + + safeTop->destroy(destintref); + /* check we don't segfault on NULL splay calls */ + safeTop = NULL; + safeTop->splay(intnode(), compareintref); + safeTop->walk(printintref, NULL); +} return 0; }