]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 1996-2025 The Squid Software Foundation and contributors | |
3 | * | |
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. | |
7 | */ | |
8 | ||
9 | /* DEBUG: section 77 Delay Pools */ | |
10 | ||
11 | #include "squid.h" | |
12 | ||
13 | #if USE_DELAY_POOLS | |
14 | #include "comm/Connection.h" | |
15 | #include "DelayTagged.h" | |
16 | #include "NullDelayId.h" | |
17 | #include "Store.h" | |
18 | ||
19 | DelayTagged::DelayTagged() | |
20 | { | |
21 | DelayPools::registerForUpdates (this); | |
22 | } | |
23 | ||
24 | static Splay<DelayTaggedBucket::Pointer>::SPLAYFREE DelayTaggedFree; | |
25 | ||
26 | DelayTagged::~DelayTagged() | |
27 | { | |
28 | DelayPools::deregisterForUpdates (this); | |
29 | buckets.destroy(DelayTaggedFree); | |
30 | } | |
31 | ||
32 | static Splay<DelayTaggedBucket::Pointer>::SPLAYCMP DelayTaggedCmp; | |
33 | ||
34 | int | |
35 | DelayTaggedCmp(DelayTaggedBucket::Pointer const &left, DelayTaggedBucket::Pointer const &right) | |
36 | { | |
37 | /* for rate limiting, case insensitive */ | |
38 | return left->tag.caseCmp(right->tag); | |
39 | } | |
40 | ||
41 | void | |
42 | DelayTaggedFree(DelayTaggedBucket::Pointer &) | |
43 | {} | |
44 | ||
45 | struct DelayTaggedStatsVisitor { | |
46 | StoreEntry *sentry; | |
47 | explicit DelayTaggedStatsVisitor(StoreEntry *se): sentry(se) {} | |
48 | void operator() (DelayTaggedBucket::Pointer const ¤t) { | |
49 | current->stats(sentry); | |
50 | } | |
51 | }; | |
52 | ||
53 | void | |
54 | DelayTagged::stats(StoreEntry * sentry) | |
55 | { | |
56 | spec.stats (sentry, "Per Tag"); | |
57 | ||
58 | if (spec.restore_bps == -1) | |
59 | return; | |
60 | ||
61 | storeAppendPrintf(sentry, "\t\tCurrent: "); | |
62 | ||
63 | if (buckets.empty()) { | |
64 | storeAppendPrintf (sentry, "Not used yet.\n\n"); | |
65 | return; | |
66 | } | |
67 | ||
68 | DelayTaggedStatsVisitor visitor(sentry); | |
69 | buckets.visit(visitor); | |
70 | storeAppendPrintf(sentry, "\n\n"); | |
71 | } | |
72 | ||
73 | void | |
74 | DelayTagged::dump(StoreEntry *entry) const | |
75 | { | |
76 | spec.dump(entry); | |
77 | } | |
78 | ||
79 | struct DelayTaggedUpdater { | |
80 | DelayTaggedUpdater (DelaySpec &_spec, int _incr):spec(_spec),incr(_incr) {}; | |
81 | ||
82 | DelaySpec spec; | |
83 | int incr; | |
84 | }; | |
85 | ||
86 | struct DelayTaggedUpdateVisitor { | |
87 | DelayTaggedUpdater *updater; | |
88 | explicit DelayTaggedUpdateVisitor(DelayTaggedUpdater *u) : updater(u) {} | |
89 | void operator() (DelayTaggedBucket::Pointer const ¤t) { | |
90 | const_cast<DelayTaggedBucket *>(current.getRaw())->theBucket.update(updater->spec, updater->incr); | |
91 | } | |
92 | }; | |
93 | ||
94 | void | |
95 | DelayTagged::update(int incr) | |
96 | { | |
97 | DelayTaggedUpdater updater(spec, incr); | |
98 | DelayTaggedUpdateVisitor visitor(&updater); | |
99 | buckets.visit(visitor); | |
100 | kickReads(); | |
101 | } | |
102 | ||
103 | void | |
104 | DelayTagged::parse() | |
105 | { | |
106 | spec.parse(); | |
107 | } | |
108 | ||
109 | DelayIdComposite::Pointer | |
110 | ||
111 | DelayTagged::id(CompositePoolNode::CompositeSelectionDetails &details) | |
112 | { | |
113 | if (!details.tag.length()) | |
114 | return new NullDelayId; | |
115 | ||
116 | return new Id(this, details.tag); | |
117 | } | |
118 | ||
119 | DelayTaggedBucket::DelayTaggedBucket(const SBuf &aTag): tag(aTag) | |
120 | { | |
121 | debugs(77, 3, "DelayTaggedBucket::DelayTaggedBucket"); | |
122 | } | |
123 | ||
124 | DelayTaggedBucket::~DelayTaggedBucket() | |
125 | { | |
126 | debugs(77, 3, "DelayTaggedBucket::~DelayTaggedBucket"); | |
127 | } | |
128 | ||
129 | void | |
130 | DelayTaggedBucket::stats(StoreEntry *entry) const | |
131 | { | |
132 | storeAppendPrintf(entry, " " SQUIDSBUFPH ":", SQUIDSBUFPRINT(tag)); | |
133 | theBucket.stats(entry); | |
134 | } | |
135 | ||
136 | DelayTagged::Id::Id(const DelayTagged::Pointer &aDelayTagged, const SBuf &aTag): theTagged(aDelayTagged) | |
137 | { | |
138 | theBucket = new DelayTaggedBucket(aTag); | |
139 | DelayTaggedBucket::Pointer const *existing = theTagged->buckets.find(theBucket, DelayTaggedCmp); | |
140 | ||
141 | if (existing) { | |
142 | theBucket = *existing; | |
143 | return; | |
144 | } | |
145 | ||
146 | theBucket->theBucket.init(theTagged->spec); | |
147 | theTagged->buckets.insert (theBucket, DelayTaggedCmp); | |
148 | } | |
149 | ||
150 | DelayTagged::Id::~Id() | |
151 | { | |
152 | debugs(77, 3, "DelayTagged::Id::~Id"); | |
153 | } | |
154 | ||
155 | int | |
156 | DelayTagged::Id::bytesWanted (int min, int max) const | |
157 | { | |
158 | return theBucket->theBucket.bytesWanted(min,max); | |
159 | } | |
160 | ||
161 | void | |
162 | DelayTagged::Id::bytesIn(int qty) | |
163 | { | |
164 | theBucket->theBucket.bytesIn(qty); | |
165 | } | |
166 | ||
167 | void | |
168 | DelayTagged::Id::delayRead(const AsyncCall::Pointer &aRead) | |
169 | { | |
170 | theTagged->delayRead(aRead); | |
171 | } | |
172 | ||
173 | #endif | |
174 |