#include "config.h"
#include "Array.h"
#include "util.h"
+#ifdef __cplusplus
+template <class V>
+class SplayNode;
+typedef SplayNode<void *> splayNode;
+#else
#include "splay.h"
+#endif
#include "memMeter.h"
#if HAVE_GNUMALLOC_H
/*
- * $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
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 V>
class SplayNode {
public:
typedef V Value;
- Value *data;
- SplayNode<V> *left;
- SplayNode<V> *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<V> *left;
+ mutable SplayNode<V> *right;
+ void destroy(SPLAYFREE *);
+ void walk(SPLAYWALKEE *, void *callerState);
+ SplayNode<V> * remove(const Value data, SPLAYCMP * compare);
+ SplayNode<V> * insert(Value data, SPLAYCMP * compare);
+ SplayNode<V> * splay(const Value &data, SPLAYCMP * compare) const;
};
-typedef SplayNode<void> splayNode;
+typedef SplayNode<void *> splayNode;
+
+template <class V>
+class Splay {
+ public:
+ typedef V Value;
+ typedef int SPLAYCMP(Value const &a, Value const &b);
+ Splay():head(NULL){}
+ mutable SplayNode<V> * 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<class V>
+void
+SplayNode<V>::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<class V>
+void
+SplayNode<V>::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<class V>
+SplayNode<V> *
+SplayNode<V>::remove(Value const data, SPLAYCMP * compare)
+{
+ if (this == NULL)
+ return NULL;
+ SplayNode<V> *result = splay(data, compare);
+ if (splayLastResult == 0) { /* found it */
+ SplayNode<V> *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<class V>
+SplayNode<V> *
+SplayNode<V>::insert(Value data, SPLAYCMP * compare)
+{
+ /* create node to insert */
+ SplayNode<V> *newNode = new SplayNode<V>;
+ newNode->data = data;
+ if (this == NULL) {
+ newNode->left = newNode->right = NULL;
+ return newNode;
+ }
+
+ SplayNode<V> *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<class V>
+SplayNode<V> *
+SplayNode<V>::splay(Value const &data, SPLAYCMP * compare) const
+{
+ if (this == NULL)
+ return NULL;
+ SplayNode<V> N;
+ SplayNode<V> *l;
+ SplayNode<V> *r;
+ SplayNode<V> *y;
+ N.left = N.right = NULL;
+ l = r = &N;
+
+ SplayNode<V> *top = const_cast<SplayNode<V> *>(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 <class V>
+typename Splay<V>::Value const *
+Splay<V>::find (Value const &value, SPLAYCMP *compare) const
+{
+ head = head->splay(value, compare);
+ if (splayLastResult != 0)
+ return NULL;
+ return &head->data;
+}
#endif
/*
- * $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
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
/* 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;
/* 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;
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
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);
}
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);
/*
- * $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
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
/*
- * $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/
#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<char*> *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<char *> *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 */
/*
- * $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 <robertc@squid-cache.org>
DelayPools::registerForUpdates (this);
}
+static SplayNode<DelayUserBucket::Pointer>::SPLAYFREE DelayUserFree;
+
DelayUser::~DelayUser()
{
DelayPools::deregisterForUpdates (this);
+ buckets.head->destroy (DelayUserFree);
+}
+
+static SplayNode<DelayUserBucket::Pointer>::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
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");
}
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<DelayUserBucket *>(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
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()
/*
- * $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 <robertc@squid-cache.org>
#include "DelayBucket.h"
#include "DelaySpec.h"
#include "Array.h"
+#include "splay.h"
class DelayUserBucket : public RefCountable {
public:
DelayUserBucket::Pointer theBucket;
};
DelaySpec spec;
- Vector<DelayUserBucket::Pointer> buckets;
- typedef Vector<DelayUserBucket::Pointer>::iterator iterator;
+ Splay<DelayUserBucket::Pointer> buckets;
};
#endif /* DELAYUSER_H */
/*
- * $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
*/
#include "squid.h"
+#include "ACL.h"
#include "ACLChecklist.h"
#include "splay.h"
#include "HttpRequest.h"
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<class T> 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
static void aclDestroyCertList(void *data);
#endif
+template<class T>
+inline void
+xRefFree(T &thing)
+{
+ xfree (thing);
+}
+
+template<class T>
+inline int
+splaystrcmp (T&l, T&r)
+{
+ return strcmp ((char *)l,(char *)r);
+}
+
+template<class T>
+inline int
+splaystrcasecmp (T&l, T&r)
+{
+ return strcasecmp ((char *)l,(char *)r);
+}
+
static squid_acl
aclStrToType(const char *s)
{
{
char *t = NULL;
acl_user_data *data;
- splayNode *Top = NULL;
+ SplayNode<char *> *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;
} 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",
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;
}
aclParseCertList(void *curlist)
{
acl_cert_data **datap = (acl_cert_data **)curlist;
- splayNode **Top;
+ SplayNode<char *> **Top;
char *t;
char *attribute = strtokFile();
if (!attribute)
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);
}
}
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<char *>(value), splaystrcmp);
return !splayLastResult;
}
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<char *>(value), splaystrcmp);
return !splayLastResult;
}
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 *
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
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;
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;
aclMatchUser(void *proxyauth_acl, char const *user)
{
acl_user_data *data = (acl_user_data *) proxyauth_acl;
- splayNode *Top = data->names;
+ SplayNode<char *> *Top = data->names;
debug(28, 7) ("aclMatchUser: user is %s, case_insensitive is %d\n",
user, data->flags.case_insensitive);
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;
}
static void
-aclFreeIpData(void *p)
+aclFreeIpData(void * &p)
{
memFree(p, MEM_ACL_IP_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;
}
#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:
/* compare two domains */
-static int
-aclDomainCompare(const void *a, const void *b)
+template<class T>
+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);
/* 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;
* 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;
* 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];
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 "
* 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);
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;
}
static void
-aclDumpDomainListWalkee(void *node, void *state)
+aclDumpDomainListWalkee(void * const &node, void *state)
{
char *domain = (char *)node;
wordlistAdd((wordlist **)state, domain);
}
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;
#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];
/* ==== 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 */
/*
- * $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/
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,
#endif
MEM_EVENT,
MEM_SWAP_LOG_DATA,
-#if USE_SSL
- MEM_ACL_CERT_DATA,
-#endif
MEM_MAX
} mem_type;
/*
- * $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
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
/*
- * $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/
#define SQUID_STRUCTS_H
#include "config.h"
-#include "splay.h"
struct _dlink_node {
void *data;
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 {
/*
- * $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/
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;
/*
- * $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
} 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<intnode *> *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<intnode> *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;
}