]>
Commit | Line | Data |
---|---|---|
88a03fda | 1 | |
2 | /* | |
262a0e14 | 3 | * $Id$ |
88a03fda | 4 | * |
5 | * DEBUG: section 77 Delay Pools | |
6 | * AUTHOR: Robert Collins <robertc@squid-cache.org> | |
7 | * | |
8 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
9 | * ---------------------------------------------------------- | |
10 | * | |
11 | * Squid is the result of efforts by numerous individuals from | |
12 | * the Internet community; see the CONTRIBUTORS file for full | |
13 | * details. Many organizations have provided support for Squid's | |
14 | * development; see the SPONSORS file for full details. Squid is | |
15 | * Copyrighted (C) 2001 by the Regents of the University of | |
16 | * California; see the COPYRIGHT file for full details. Squid | |
17 | * incorporates software developed and/or copyrighted by other | |
18 | * sources; see the CREDITS file for full details. | |
19 | * | |
20 | * This program is free software; you can redistribute it and/or modify | |
21 | * it under the terms of the GNU General Public License as published by | |
22 | * the Free Software Foundation; either version 2 of the License, or | |
23 | * (at your option) any later version. | |
26ac0430 | 24 | * |
88a03fda | 25 | * This program is distributed in the hope that it will be useful, |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | * GNU General Public License for more details. | |
26ac0430 | 29 | * |
88a03fda | 30 | * You should have received a copy of the GNU General Public License |
31 | * along with this program; if not, write to the Free Software | |
32 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
33 | * | |
34 | * | |
35 | * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org> | |
36 | */ | |
37 | ||
38 | #include "config.h" | |
39 | ||
40 | #if DELAY_POOLS | |
41 | #include "squid.h" | |
42 | #include "DelayUser.h" | |
f5691f9c | 43 | #include "AuthUserRequest.h" |
44 | #include "AuthUser.h" | |
88a03fda | 45 | #include "NullDelayId.h" |
46 | #include "Store.h" | |
47 | ||
48 | void * | |
49 | DelayUser::operator new(size_t size) | |
50 | { | |
51 | DelayPools::MemoryUsed += sizeof (DelayUser); | |
52 | return ::operator new (size); | |
53 | } | |
54 | ||
55 | void | |
56 | DelayUser::operator delete (void *address) | |
57 | { | |
58 | DelayPools::MemoryUsed -= sizeof (DelayUser); | |
59 | ::operator delete (address); | |
60 | } | |
61 | ||
88a03fda | 62 | DelayUser::DelayUser() |
63 | { | |
64 | DelayPools::registerForUpdates (this); | |
65 | } | |
66 | ||
29b17d63 | 67 | static SplayNode<DelayUserBucket::Pointer>::SPLAYFREE DelayUserFree; |
68 | ||
88a03fda | 69 | DelayUser::~DelayUser() |
70 | { | |
71 | DelayPools::deregisterForUpdates (this); | |
29b17d63 | 72 | buckets.head->destroy (DelayUserFree); |
73 | } | |
74 | ||
75 | static SplayNode<DelayUserBucket::Pointer>::SPLAYCMP DelayUserCmp; | |
76 | ||
77 | int | |
78 | DelayUserCmp(DelayUserBucket::Pointer const &left, DelayUserBucket::Pointer const &right) | |
79 | { | |
80 | /* for rate limiting, case insensitive */ | |
81 | return strcasecmp(left->authUser->username(), right->authUser->username()); | |
82 | } | |
83 | ||
84 | void | |
85 | DelayUserFree(DelayUserBucket::Pointer &) | |
62e76326 | 86 | {} |
29b17d63 | 87 | |
88 | void | |
89 | DelayUserStatsWalkee(DelayUserBucket::Pointer const ¤t, void *state) | |
90 | { | |
91 | current->stats ((StoreEntry *)state); | |
88a03fda | 92 | } |
93 | ||
94 | void | |
95 | DelayUser::stats(StoreEntry * sentry) | |
96 | { | |
97 | spec.stats (sentry, "Per User"); | |
62e76326 | 98 | |
88a03fda | 99 | if (spec.restore_bps == -1) |
62e76326 | 100 | return; |
101 | ||
88a03fda | 102 | storeAppendPrintf(sentry, "\t\tCurrent: "); |
62e76326 | 103 | |
29b17d63 | 104 | if (!buckets.head) { |
62e76326 | 105 | storeAppendPrintf (sentry, "Not used yet.\n\n"); |
106 | return; | |
88a03fda | 107 | } |
62e76326 | 108 | |
29b17d63 | 109 | buckets.head->walk(DelayUserStatsWalkee, sentry); |
88a03fda | 110 | storeAppendPrintf(sentry, "\n\n"); |
111 | } | |
112 | ||
113 | void | |
114 | DelayUser::dump(StoreEntry *entry) const | |
115 | { | |
116 | spec.dump(entry); | |
117 | } | |
118 | ||
26ac0430 AJ |
119 | struct DelayUserUpdater { |
120 | DelayUserUpdater (DelaySpec &_spec, int _incr):spec(_spec),incr(_incr) {}; | |
62e76326 | 121 | |
29b17d63 | 122 | DelaySpec spec; |
123 | int incr; | |
124 | }; | |
62e76326 | 125 | |
29b17d63 | 126 | void |
127 | DelayUserUpdateWalkee(DelayUserBucket::Pointer const ¤t, void *state) | |
128 | { | |
129 | DelayUserUpdater *t = (DelayUserUpdater *)state; | |
130 | /* This doesn't change the value of the DelayUserBucket, so is safe */ | |
131 | const_cast<DelayUserBucket *>(current.getRaw())->theBucket.update(t->spec, t->incr); | |
132 | } | |
62e76326 | 133 | |
88a03fda | 134 | void |
135 | DelayUser::update(int incr) | |
136 | { | |
29b17d63 | 137 | DelayUserUpdater updater(spec, incr); |
138 | buckets.head->walk (DelayUserUpdateWalkee, &updater); | |
88a03fda | 139 | } |
140 | ||
141 | void | |
142 | DelayUser::parse() | |
143 | { | |
144 | spec.parse(); | |
145 | } | |
146 | ||
147 | DelayIdComposite::Pointer | |
1e5562e3 | 148 | DelayUser::id(CompositePoolNode::CompositeSelectionDetails &details) |
88a03fda | 149 | { |
1e5562e3 | 150 | if (!details.user) |
62e76326 | 151 | return new NullDelayId; |
152 | ||
f5691f9c | 153 | return new Id(this, details.user->user()); |
88a03fda | 154 | } |
155 | ||
156 | void * | |
157 | DelayUser::Id::operator new(size_t size) | |
158 | { | |
159 | DelayPools::MemoryUsed += sizeof (Id); | |
160 | return ::operator new (size); | |
161 | } | |
162 | ||
163 | void | |
164 | DelayUser::Id::operator delete (void *address) | |
165 | { | |
166 | DelayPools::MemoryUsed -= sizeof (Id); | |
167 | ::operator delete (address); | |
168 | } | |
169 | ||
88a03fda | 170 | void * |
171 | DelayUserBucket::operator new(size_t size) | |
172 | { | |
173 | DelayPools::MemoryUsed += sizeof (DelayUserBucket); | |
174 | return ::operator new (size); | |
175 | } | |
176 | ||
177 | void | |
178 | DelayUserBucket::operator delete (void *address) | |
179 | { | |
180 | DelayPools::MemoryUsed -= sizeof (DelayUserBucket); | |
181 | ::operator delete (address); | |
182 | } | |
183 | ||
184 | DelayUserBucket::DelayUserBucket(AuthUser *aUser) : authUser (aUser) | |
185 | { | |
bf8fe701 | 186 | debugs(77, 3, "DelayUserBucket::DelayUserBucket"); |
f5691f9c | 187 | |
3d0ac046 | 188 | authUser->lock(); |
88a03fda | 189 | } |
190 | ||
191 | DelayUserBucket::~DelayUserBucket() | |
192 | { | |
f5691f9c | 193 | authUser->unlock(); |
bf8fe701 | 194 | debugs(77, 3, "DelayUserBucket::~DelayUserBucket"); |
88a03fda | 195 | } |
196 | ||
197 | void | |
198 | DelayUserBucket::stats (StoreEntry *entry) const | |
199 | { | |
200 | storeAppendPrintf(entry, " %s:", authUser->username()); | |
201 | theBucket.stats (entry); | |
202 | } | |
203 | ||
204 | DelayUser::Id::Id(DelayUser::Pointer aDelayUser,AuthUser *aUser) : theUser(aDelayUser) | |
205 | { | |
88a03fda | 206 | theBucket = new DelayUserBucket(aUser); |
29b17d63 | 207 | DelayUserBucket::Pointer const *existing = theUser->buckets.find(theBucket, DelayUserCmp); |
62e76326 | 208 | |
29b17d63 | 209 | if (existing) { |
62e76326 | 210 | theBucket = *existing; |
211 | return; | |
29b17d63 | 212 | } |
62e76326 | 213 | |
88a03fda | 214 | theBucket->theBucket.init(theUser->spec); |
29b17d63 | 215 | theUser->buckets.head = theUser->buckets.head->insert (theBucket, DelayUserCmp); |
88a03fda | 216 | } |
217 | ||
218 | DelayUser::Id::~Id() | |
219 | { | |
bf8fe701 | 220 | debugs(77, 3, "DelayUser::Id::~Id"); |
88a03fda | 221 | } |
222 | ||
223 | int | |
224 | DelayUser::Id::bytesWanted (int min, int max) const | |
225 | { | |
226 | return theBucket->theBucket.bytesWanted(min,max); | |
227 | } | |
228 | ||
229 | void | |
230 | DelayUser::Id::bytesIn(int qty) | |
231 | { | |
232 | theBucket->theBucket.bytesIn(qty); | |
233 | } | |
62e76326 | 234 | |
88a03fda | 235 | #endif |