3 * DEBUG: section 77 Delay Pools
4 * AUTHOR: Robert Collins <robertc@squid-cache.org>
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
33 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
38 #if USE_DELAY_POOLS && USE_AUTH
39 #include "auth/User.h"
40 #include "auth/UserRequest.h"
41 #include "comm/Connection.h"
42 #include "DelayUser.h"
43 #include "NullDelayId.h"
47 DelayUser::operator new(size_t size
)
49 DelayPools::MemoryUsed
+= sizeof (DelayUser
);
50 return ::operator new (size
);
54 DelayUser::operator delete (void *address
)
56 DelayPools::MemoryUsed
-= sizeof (DelayUser
);
57 ::operator delete (address
);
60 DelayUser::DelayUser()
62 DelayPools::registerForUpdates (this);
65 static SplayNode
<DelayUserBucket::Pointer
>::SPLAYFREE DelayUserFree
;
67 DelayUser::~DelayUser()
69 DelayPools::deregisterForUpdates (this);
70 buckets
.head
->destroy (DelayUserFree
);
73 static SplayNode
<DelayUserBucket::Pointer
>::SPLAYCMP DelayUserCmp
;
76 DelayUserCmp(DelayUserBucket::Pointer
const &left
, DelayUserBucket::Pointer
const &right
)
78 /* Verify for re-currance of Bug 2127. either of these missing will crash strcasecmp() */
79 assert(left
->authUser
->username() != NULL
);
80 assert(right
->authUser
->username() != NULL
);
82 /* for rate limiting, case insensitive */
83 return strcasecmp(left
->authUser
->username(), right
->authUser
->username());
87 DelayUserFree(DelayUserBucket::Pointer
&)
91 DelayUserStatsWalkee(DelayUserBucket::Pointer
const ¤t
, void *state
)
93 current
->stats ((StoreEntry
*)state
);
97 DelayUser::stats(StoreEntry
* sentry
)
99 spec
.stats (sentry
, "Per User");
101 if (spec
.restore_bps
== -1)
104 storeAppendPrintf(sentry
, "\t\tCurrent: ");
107 storeAppendPrintf (sentry
, "Not used yet.\n\n");
111 buckets
.head
->walk(DelayUserStatsWalkee
, sentry
);
112 storeAppendPrintf(sentry
, "\n\n");
116 DelayUser::dump(StoreEntry
*entry
) const
121 struct DelayUserUpdater
{
122 DelayUserUpdater (DelaySpec
&_spec
, int _incr
):spec(_spec
),incr(_incr
) {};
129 DelayUserUpdateWalkee(DelayUserBucket::Pointer
const ¤t
, void *state
)
131 DelayUserUpdater
*t
= (DelayUserUpdater
*)state
;
132 /* This doesn't change the value of the DelayUserBucket, so is safe */
133 const_cast<DelayUserBucket
*>(current
.getRaw())->theBucket
.update(t
->spec
, t
->incr
);
137 DelayUser::update(int incr
)
139 DelayUserUpdater
updater(spec
, incr
);
140 buckets
.head
->walk (DelayUserUpdateWalkee
, &updater
);
149 DelayIdComposite::Pointer
150 DelayUser::id(CompositePoolNode::CompositeSelectionDetails
&details
)
152 if (!details
.user
|| !details
.user
->user() || !details
.user
->user()->username())
153 return new NullDelayId
;
155 debugs(77, 3, HERE
<< "Adding a slow-down for User '" << details
.user
->user()->username() << "'");
156 return new Id(this, details
.user
->user());
160 DelayUser::Id::operator new(size_t size
)
162 DelayPools::MemoryUsed
+= sizeof (Id
);
163 return ::operator new (size
);
167 DelayUser::Id::operator delete (void *address
)
169 DelayPools::MemoryUsed
-= sizeof (Id
);
170 ::operator delete (address
);
174 DelayUserBucket::operator new(size_t size
)
176 DelayPools::MemoryUsed
+= sizeof (DelayUserBucket
);
177 return ::operator new (size
);
181 DelayUserBucket::operator delete(void *address
)
183 DelayPools::MemoryUsed
-= sizeof(DelayUserBucket
);
184 ::operator delete(address
);
187 DelayUserBucket::DelayUserBucket(Auth::User::Pointer aUser
) : authUser(aUser
)
189 debugs(77, 3, "DelayUserBucket::DelayUserBucket");
192 DelayUserBucket::~DelayUserBucket()
195 debugs(77, 3, "DelayUserBucket::~DelayUserBucket");
199 DelayUserBucket::stats (StoreEntry
*entry
) const
201 storeAppendPrintf(entry
, " %s:", authUser
->username());
202 theBucket
.stats(entry
);
205 DelayUser::Id::Id(DelayUser::Pointer aDelayUser
, Auth::User::Pointer aUser
) : theUser(aDelayUser
)
207 theBucket
= new DelayUserBucket(aUser
);
208 DelayUserBucket::Pointer
const *existing
= theUser
->buckets
.find(theBucket
, DelayUserCmp
);
211 theBucket
= *existing
;
215 theBucket
->theBucket
.init(theUser
->spec
);
216 theUser
->buckets
.head
= theUser
->buckets
.head
->insert (theBucket
, DelayUserCmp
);
221 debugs(77, 3, "DelayUser::Id::~Id");
225 DelayUser::Id::bytesWanted (int min
, int max
) const
227 return theBucket
->theBucket
.bytesWanted(min
,max
);
231 DelayUser::Id::bytesIn(int qty
)
233 theBucket
->theBucket
.bytesIn(qty
);
236 #endif /* USE_DELAY_POOLS && USE_AUTH */