]>
Commit | Line | Data |
---|---|---|
1e5562e3 | 1 | /* |
bde978a6 | 2 | * Copyright (C) 1996-2015 The Squid Software Foundation and contributors |
26ac0430 | 3 | * |
bbc27441 AJ |
4 | * Squid software is distributed under GPLv2+ license and includes |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
1e5562e3 | 7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 77 Delay Pools */ |
10 | ||
f7f3304a | 11 | #include "squid.h" |
1e5562e3 | 12 | |
9a0a18de | 13 | #if USE_DELAY_POOLS |
1b76e6c1 | 14 | #include "comm/Connection.h" |
1e5562e3 | 15 | #include "DelayTagged.h" |
1e5562e3 | 16 | #include "NullDelayId.h" |
17 | #include "Store.h" | |
18 | ||
19 | void * | |
20 | DelayTagged::operator new(size_t size) | |
21 | { | |
22 | DelayPools::MemoryUsed += sizeof (DelayTagged); | |
23 | return ::operator new (size); | |
24 | } | |
25 | ||
26 | void | |
27 | DelayTagged::operator delete (void *address) | |
28 | { | |
29 | DelayPools::MemoryUsed -= sizeof (DelayTagged); | |
30 | ::operator delete (address); | |
31 | } | |
32 | ||
1e5562e3 | 33 | DelayTagged::DelayTagged() |
34 | { | |
35 | DelayPools::registerForUpdates (this); | |
36 | } | |
37 | ||
1e4f953d | 38 | static Splay<DelayTaggedBucket::Pointer>::SPLAYFREE DelayTaggedFree; |
1e5562e3 | 39 | |
40 | DelayTagged::~DelayTagged() | |
41 | { | |
42 | DelayPools::deregisterForUpdates (this); | |
d6349cfb | 43 | buckets.destroy(DelayTaggedFree); |
1e5562e3 | 44 | } |
45 | ||
1e4f953d | 46 | static Splay<DelayTaggedBucket::Pointer>::SPLAYCMP DelayTaggedCmp; |
1e5562e3 | 47 | |
48 | int | |
49 | DelayTaggedCmp(DelayTaggedBucket::Pointer const &left, DelayTaggedBucket::Pointer const &right) | |
50 | { | |
51 | /* for rate limiting, case insensitive */ | |
bb790702 | 52 | return left->tag.caseCmp(right->tag); |
1e5562e3 | 53 | } |
54 | ||
55 | void | |
56 | DelayTaggedFree(DelayTaggedBucket::Pointer &) | |
57 | {} | |
58 | ||
f5dc4237 FC |
59 | struct DelayTaggedStatsVisitor { |
60 | StoreEntry *sentry; | |
d6349cfb | 61 | explicit DelayTaggedStatsVisitor(StoreEntry *se): sentry(se) {} |
f5dc4237 FC |
62 | void operator() (DelayTaggedBucket::Pointer const ¤t) { |
63 | current->stats(sentry); | |
64 | } | |
65 | }; | |
1e5562e3 | 66 | |
67 | void | |
68 | DelayTagged::stats(StoreEntry * sentry) | |
69 | { | |
70 | spec.stats (sentry, "Per Tag"); | |
71 | ||
72 | if (spec.restore_bps == -1) | |
73 | return; | |
74 | ||
75 | storeAppendPrintf(sentry, "\t\tCurrent: "); | |
76 | ||
f5dc4237 | 77 | if (buckets.empty()) { |
1e5562e3 | 78 | storeAppendPrintf (sentry, "Not used yet.\n\n"); |
79 | return; | |
80 | } | |
81 | ||
f5dc4237 FC |
82 | DelayTaggedStatsVisitor visitor(sentry); |
83 | buckets.visit(visitor); | |
1e5562e3 | 84 | storeAppendPrintf(sentry, "\n\n"); |
85 | } | |
86 | ||
87 | void | |
88 | DelayTagged::dump(StoreEntry *entry) const | |
89 | { | |
90 | spec.dump(entry); | |
91 | } | |
92 | ||
26ac0430 AJ |
93 | struct DelayTaggedUpdater { |
94 | DelayTaggedUpdater (DelaySpec &_spec, int _incr):spec(_spec),incr(_incr) {}; | |
1e5562e3 | 95 | |
96 | DelaySpec spec; | |
97 | int incr; | |
98 | }; | |
99 | ||
100 | void | |
101 | DelayTaggedUpdateWalkee(DelayTaggedBucket::Pointer const ¤t, void *state) | |
102 | { | |
103 | DelayTaggedUpdater *t = (DelayTaggedUpdater *)state; | |
104 | /* This doesn't change the value of the DelayTaggedBucket, so is safe */ | |
105 | const_cast<DelayTaggedBucket *>(current.getRaw())->theBucket.update(t->spec, t->incr); | |
106 | } | |
107 | ||
d6349cfb FC |
108 | struct DelayTaggedUpdateVisitor { |
109 | DelayTaggedUpdater *updater; | |
110 | explicit DelayTaggedUpdateVisitor(DelayTaggedUpdater *u) : updater(u) {} | |
111 | void operator() (DelayTaggedBucket::Pointer const ¤t) { | |
112 | const_cast<DelayTaggedBucket *>(current.getRaw())->theBucket.update(updater->spec, updater->incr); | |
113 | } | |
114 | }; | |
115 | ||
1e5562e3 | 116 | void |
117 | DelayTagged::update(int incr) | |
118 | { | |
119 | DelayTaggedUpdater updater(spec, incr); | |
d6349cfb FC |
120 | DelayTaggedUpdateVisitor visitor(&updater); |
121 | buckets.visit(visitor); | |
44453ab4 | 122 | kickReads(); |
1e5562e3 | 123 | } |
124 | ||
125 | void | |
126 | DelayTagged::parse() | |
127 | { | |
128 | spec.parse(); | |
129 | } | |
130 | ||
131 | DelayIdComposite::Pointer | |
132 | ||
133 | DelayTagged::id(CompositePoolNode::CompositeSelectionDetails &details) | |
134 | { | |
135 | if (!details.tag.size()) | |
136 | return new NullDelayId; | |
137 | ||
138 | return new Id(this, details.tag); | |
139 | } | |
140 | ||
141 | void * | |
142 | DelayTagged::Id::operator new(size_t size) | |
143 | { | |
144 | DelayPools::MemoryUsed += sizeof (Id); | |
145 | return ::operator new (size); | |
146 | } | |
147 | ||
148 | void | |
149 | DelayTagged::Id::operator delete (void *address) | |
150 | { | |
151 | DelayPools::MemoryUsed -= sizeof (Id); | |
152 | ::operator delete (address); | |
153 | } | |
154 | ||
1e5562e3 | 155 | void * |
156 | DelayTaggedBucket::operator new(size_t size) | |
157 | { | |
158 | DelayPools::MemoryUsed += sizeof (DelayTaggedBucket); | |
159 | return ::operator new (size); | |
160 | } | |
161 | ||
162 | void | |
163 | DelayTaggedBucket::operator delete (void *address) | |
164 | { | |
165 | DelayPools::MemoryUsed -= sizeof (DelayTaggedBucket); | |
166 | ::operator delete (address); | |
167 | } | |
168 | ||
30abd221 | 169 | DelayTaggedBucket::DelayTaggedBucket(String &aTag) : tag (aTag) |
1e5562e3 | 170 | { |
bf8fe701 | 171 | debugs(77, 3, "DelayTaggedBucket::DelayTaggedBucket"); |
1e5562e3 | 172 | } |
173 | ||
174 | DelayTaggedBucket::~DelayTaggedBucket() | |
175 | { | |
bf8fe701 | 176 | debugs(77, 3, "DelayTaggedBucket::~DelayTaggedBucket"); |
1e5562e3 | 177 | } |
178 | ||
179 | void | |
78b06ec5 | 180 | DelayTaggedBucket::stats(StoreEntry *entry) const |
1e5562e3 | 181 | { |
78b06ec5 AJ |
182 | storeAppendPrintf(entry, " " SQUIDSTRINGPH ":", SQUIDSTRINGPRINT(tag)); |
183 | theBucket.stats(entry); | |
1e5562e3 | 184 | } |
185 | ||
30abd221 | 186 | DelayTagged::Id::Id(DelayTagged::Pointer aDelayTagged, String &aTag) : theTagged(aDelayTagged) |
1e5562e3 | 187 | { |
188 | theBucket = new DelayTaggedBucket(aTag); | |
189 | DelayTaggedBucket::Pointer const *existing = theTagged->buckets.find(theBucket, DelayTaggedCmp); | |
190 | ||
191 | if (existing) { | |
192 | theBucket = *existing; | |
193 | return; | |
194 | } | |
195 | ||
196 | theBucket->theBucket.init(theTagged->spec); | |
d6349cfb | 197 | theTagged->buckets.insert (theBucket, DelayTaggedCmp); |
1e5562e3 | 198 | } |
199 | ||
200 | DelayTagged::Id::~Id() | |
201 | { | |
bf8fe701 | 202 | debugs(77, 3, "DelayTagged::Id::~Id"); |
1e5562e3 | 203 | } |
204 | ||
205 | int | |
206 | DelayTagged::Id::bytesWanted (int min, int max) const | |
207 | { | |
208 | return theBucket->theBucket.bytesWanted(min,max); | |
209 | } | |
210 | ||
211 | void | |
212 | DelayTagged::Id::bytesIn(int qty) | |
213 | { | |
214 | theBucket->theBucket.bytesIn(qty); | |
215 | } | |
216 | ||
288d8048 | 217 | void |
218 | DelayTagged::Id::delayRead(DeferredRead const &aRead) | |
219 | { | |
220 | theTagged->delayRead(aRead); | |
221 | } | |
222 | ||
1e5562e3 | 223 | #endif |
f53969cc | 224 |