]> git.ipfire.org Git - thirdparty/squid.git/blame - src/delay_pools.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / src / delay_pools.cc
CommitLineData
95e36d02 1/*
95e36d02 2 * DEBUG: section 77 Delay Pools
b67e2c8c 3 * AUTHOR: Robert Collins <robertc@squid-cache.org>
4 * Based upon original delay pools code by
5 * David Luyer <david@luyer.net>
95e36d02 6 *
2b6662ba 7 * SQUID Web Proxy Cache http://www.squid-cache.org/
95e36d02 8 * ----------------------------------------------------------
9 *
2b6662ba 10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
95e36d02 18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
26ac0430 23 *
95e36d02 24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
26ac0430 28 *
95e36d02 29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
32 *
b67e2c8c 33 *
34 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
95e36d02 35 */
36
63be0a78 37/**
38 \defgroup DelayPoolsInternal Delay Pools Internal
39 \ingroup DelayPoolsAPI
40 */
41
f7f3304a 42#include "squid.h"
95e36d02 43
9a0a18de 44#if USE_DELAY_POOLS
f7f3304a 45#include "squid-old.h"
8822ebee 46#include "mgr/Registration.h"
b67e2c8c 47#include "DelaySpec.h"
48#include "DelayPools.h"
a553a5a3 49#include "event.h"
fc582e0f 50#include "StoreClient.h"
01a13aec 51#include "Store.h"
528b2c61 52#include "MemObject.h"
53#include "client_side_request.h"
a80a77cf 54#include "ConfigParser.h"
b67e2c8c 55#include "DelayId.h"
56#include "Array.h"
57#include "SquidString.h"
985c86bc 58#include "SquidTime.h"
b67e2c8c 59#include "CommonPool.h"
60#include "CompositePoolNode.h"
61#include "DelayPool.h"
62#include "DelayVector.h"
63#include "NullDelayId.h"
64#include "DelayBucket.h"
65#include "DelayUser.h"
1e5562e3 66#include "DelayTagged.h"
96d89ea0 67#include "ip/Address.h"
1b76e6c1 68#include "comm/Connection.h"
95e36d02 69
63be0a78 70/// \ingroup DelayPoolsInternal
b67e2c8c 71long DelayPools::MemoryUsed = 0;
72
63be0a78 73/// \ingroup DelayPoolsInternal
62e76326 74class Aggregate : public CompositePoolNode
75{
76
77public:
b67e2c8c 78 typedef RefCount<Aggregate> Pointer;
79 void *operator new(size_t);
80 void operator delete (void *);
b67e2c8c 81 Aggregate();
82 ~Aggregate();
83 virtual DelaySpec *rate() {return &spec;}
62e76326 84
b67e2c8c 85 virtual DelaySpec const *rate() const {return &spec;}
62e76326 86
b67e2c8c 87 virtual void stats(StoreEntry * sentry);
88 virtual void dump(StoreEntry *entry) const;
89 virtual void update(int incr);
90 virtual void parse();
62e76326 91
1e5562e3 92 virtual DelayIdComposite::Pointer id(CompositeSelectionDetails &);
62e76326 93
94private:
95
63be0a78 96 /// \ingroup DelayPoolsInternal
97 class AggregateId:public DelayIdComposite
62e76326 98 {
99
100 public:
101 void *operator new(size_t);
102 void operator delete (void *);
75566ba2 103 AggregateId (RefCount<Aggregate>);
62e76326 104 virtual int bytesWanted (int min, int max) const;
105 virtual void bytesIn(int qty);
a46d2c0e 106 virtual void delayRead(DeferredRead const &);
62e76326 107
108 private:
75566ba2 109 RefCount<Aggregate> theAggregate;
b67e2c8c 110 };
62e76326 111
f5e92ca2 112 friend class AggregateId;
113
b67e2c8c 114 DelayBucket theBucket;
115 DelaySpec spec;
59715b38 116};
117
63be0a78 118/// \ingroup DelayPoolsInternal
b67e2c8c 119template <class Key, class Value>
62e76326 120class VectorMap
121{
122
123public:
b67e2c8c 124 VectorMap();
125 unsigned int size() const;
126 unsigned char findKeyIndex (Key const key) const;
127 bool indexUsed (unsigned char const index) const;
128 unsigned int insert (Key const key);
62e76326 129
efd900cb 130#define IND_MAP_SZ 256
62e76326 131
b67e2c8c 132 Key key_map[IND_MAP_SZ];
133 Value values[IND_MAP_SZ];
62e76326 134
135private:
b67e2c8c 136 unsigned int nextMapPosition;
137};
efd900cb 138
63be0a78 139/// \ingroup DelayPoolsInternal
62e76326 140class VectorPool : public CompositePoolNode
141{
142
143public:
b67e2c8c 144 typedef RefCount<VectorPool> Pointer;
145 virtual void dump(StoreEntry *entry) const;
146 virtual void parse();
147 virtual void update(int incr);
148 virtual void stats(StoreEntry * sentry);
62e76326 149
1e5562e3 150 virtual DelayIdComposite::Pointer id(CompositeSelectionDetails &);
b67e2c8c 151 VectorMap<unsigned char, DelayBucket> buckets;
152 VectorPool();
153 ~VectorPool();
62e76326 154
155protected:
b67e2c8c 156 bool keyAllocated (unsigned char const key) const;
157 virtual DelaySpec *rate() {return &spec;}
62e76326 158
b67e2c8c 159 virtual DelaySpec const *rate() const {return &spec;}
62e76326 160
b67e2c8c 161 virtual char const *label() const = 0;
62e76326 162
b7ac5457 163 virtual unsigned int makeKey(Ip::Address &src_addr) const = 0;
b67e2c8c 164
165 DelaySpec spec;
62e76326 166
63be0a78 167 /// \ingroup DelayPoolsInternal
168 class Id:public DelayIdComposite
62e76326 169 {
170
171 public:
172 void *operator new(size_t);
173 void operator delete (void *);
75566ba2 174 Id (RefCount<VectorPool>, int);
62e76326 175 virtual int bytesWanted (int min, int max) const;
176 virtual void bytesIn(int qty);
177
178 private:
75566ba2 179 RefCount<VectorPool> theVector;
62e76326 180 int theIndex;
b67e2c8c 181 };
95e36d02 182};
183
63be0a78 184/// \ingroup DelayPoolsInternal
62e76326 185class IndividualPool : public VectorPool
186{
187
188public:
b67e2c8c 189 void *operator new(size_t);
b1fb3348 190 void operator delete(void *);
62e76326 191
192protected:
b67e2c8c 193 virtual char const *label() const {return "Individual";}
b7ac5457 194 virtual unsigned int makeKey(Ip::Address &src_addr) const;
59715b38 195};
196
63be0a78 197/// \ingroup DelayPoolsInternal
62e76326 198class ClassCNetPool : public VectorPool
199{
200
201public:
b67e2c8c 202 void *operator new(size_t);
203 void operator delete (void *);
62e76326 204
205protected:
b67e2c8c 206 virtual char const *label() const {return "Network";}
b7ac5457 207 virtual unsigned int makeKey (Ip::Address &src_addr) const;
b67e2c8c 208};
59715b38 209
b67e2c8c 210/* don't use remote storage for these */
63be0a78 211/// \ingroup DelayPoolsInternal
62e76326 212class ClassCBucket
213{
214
215public:
b67e2c8c 216 bool individualUsed (unsigned int index)const;
217 unsigned char findHostMapPosition (unsigned char const host) const;
218 bool individualAllocated (unsigned char host) const;
219 unsigned char hostPosition (DelaySpec &rate, unsigned char const host);
220 void initHostIndex (DelaySpec &rate, unsigned char index, unsigned char host);
221 void update (DelaySpec const &, int incr);
222 void stats(StoreEntry *)const;
62e76326 223
b67e2c8c 224 DelayBucket net;
225 VectorMap<unsigned char, DelayBucket> individuals;
59715b38 226};
227
63be0a78 228/// \ingroup DelayPoolsInternal
62e76326 229class ClassCHostPool : public CompositePoolNode
230{
231
232public:
b67e2c8c 233 typedef RefCount<ClassCHostPool> Pointer;
234 virtual void dump(StoreEntry *entry) const;
235 virtual void parse();
236 virtual void update(int incr);
237 virtual void stats(StoreEntry * sentry);
62e76326 238
1e5562e3 239 virtual DelayIdComposite::Pointer id(CompositeSelectionDetails &);
b67e2c8c 240 ClassCHostPool();
241 ~ClassCHostPool();
62e76326 242
243protected:
b67e2c8c 244 bool keyAllocated (unsigned char const key) const;
245 virtual DelaySpec *rate() {return &spec;}
62e76326 246
b67e2c8c 247 virtual DelaySpec const *rate() const {return &spec;}
62e76326 248
b67e2c8c 249 virtual char const *label() const {return "Individual";}
62e76326 250
b7ac5457 251 virtual unsigned int makeKey(Ip::Address &src_addr) const;
62e76326 252
b7ac5457 253 unsigned char makeHostKey(Ip::Address &src_addr) const;
b67e2c8c 254
255 DelaySpec spec;
256 VectorMap<unsigned char, ClassCBucket> buckets;
62e76326 257
0353e724 258 class Id;
259
260 friend class ClassCHostPool::Id;
261
63be0a78 262 /// \ingroup DelayPoolsInternal
263 class Id:public DelayIdComposite
62e76326 264 {
265
266 public:
267 void *operator new(size_t);
268 void operator delete (void *);
75566ba2 269 Id (RefCount<ClassCHostPool>, unsigned char, unsigned char);
62e76326 270 virtual int bytesWanted (int min, int max) const;
271 virtual void bytesIn(int qty);
272
273 private:
75566ba2 274 RefCount<ClassCHostPool> theClassCHost;
62e76326 275 unsigned char theNet;
276 unsigned char theHost;
b67e2c8c 277 };
278};
279
a46d2c0e 280void
281Aggregate::AggregateId::delayRead(DeferredRead const &aRead)
282{
283 theAggregate->delayRead(aRead);
284}
b67e2c8c 285
286void *
287CommonPool::operator new(size_t size)
288{
289 DelayPools::MemoryUsed += sizeof (CommonPool);
290 return ::operator new (size);
b6a2f15e 291}
292
b67e2c8c 293void
b1fb3348 294CommonPool::operator delete(void *address)
b6a2f15e 295{
b1fb3348
AJ
296 DelayPools::MemoryUsed -= sizeof(CommonPool);
297 ::operator delete(address);
b6a2f15e 298}
299
b67e2c8c 300CommonPool *
301CommonPool::Factory(unsigned char _class, CompositePoolNode::Pointer& compositeCopy)
302{
303 CommonPool *result = new CommonPool;
62e76326 304
b67e2c8c 305 switch (_class) {
62e76326 306
307 case 0:
308 break;
309
310 case 1:
311 compositeCopy = new Aggregate;
312 result->typeLabel = "1";
313 break;
314
315 case 2:
316 result->typeLabel = "2";
317 {
318 DelayVector::Pointer temp = new DelayVector;
319 compositeCopy = temp.getRaw();
320 temp->push_back (new Aggregate);
321 temp->push_back(new IndividualPool);
322 }
62e76326 323 break;
324
325 case 3:
326 result->typeLabel = "3";
327 {
328 DelayVector::Pointer temp = new DelayVector;
329 compositeCopy = temp.getRaw();
330 temp->push_back (new Aggregate);
331 temp->push_back (new ClassCNetPool);
332 temp->push_back (new ClassCHostPool);
333 }
62e76326 334 break;
335
336 case 4:
337 result->typeLabel = "4";
338 {
339 DelayVector::Pointer temp = new DelayVector;
340 compositeCopy = temp.getRaw();
341 temp->push_back (new Aggregate);
342 temp->push_back (new ClassCNetPool);
343 temp->push_back (new ClassCHostPool);
79fc6915 344#if USE_AUTH
62e76326 345 temp->push_back (new DelayUser);
79fc6915 346#endif
62e76326 347 }
62e76326 348 break;
349
1e5562e3 350 case 5:
351 result->typeLabel = "5";
352 compositeCopy = new DelayTagged;
353 break;
354
62e76326 355 default:
b67e2c8c 356 fatal ("unknown delay pool class");
62e76326 357 return NULL;
b67e2c8c 358 };
359
360 return result;
361}
362
62e76326 363CommonPool::CommonPool()
364{}
59715b38 365
366void
b67e2c8c 367ClassCBucket::update (DelaySpec const &rate, int incr)
59715b38 368{
b67e2c8c 369 /* If we aren't active, don't try to update us ! */
370 assert (rate.restore_bps != -1);
371
372 for (unsigned char j = 0; j < individuals.size(); ++j)
62e76326 373 individuals.values[j].update (rate, incr);
b67e2c8c 374}
375
376void
377ClassCBucket::stats(StoreEntry *sentry)const
378{
379 for (unsigned int j = 0; j < individuals.size(); ++j) {
62e76326 380 assert (individualUsed (j));
381 storeAppendPrintf(sentry, " %d:",individuals.key_map[j]);
382 individuals.values[j].stats (sentry);
b67e2c8c 383 }
384}
385
386unsigned char
387ClassCBucket::findHostMapPosition (unsigned char const host) const
388{
389 return individuals.findKeyIndex(host);
390}
391
392bool
393ClassCBucket::individualUsed (unsigned int index)const
394{
395 return individuals.indexUsed(index);
396}
397
398bool
399ClassCBucket::individualAllocated (unsigned char host) const
400{
401 return individualUsed(findHostMapPosition (host));
b6a2f15e 402}
403
b67e2c8c 404unsigned char
405ClassCBucket::hostPosition (DelaySpec &rate, unsigned char const host)
b6a2f15e 406{
b67e2c8c 407 if (individualAllocated (host))
62e76326 408 return findHostMapPosition(host);
b67e2c8c 409
410 assert (!individualUsed (findHostMapPosition(host)));
62e76326 411
b67e2c8c 412 unsigned char result = findHostMapPosition(host);
62e76326 413
b67e2c8c 414 initHostIndex (rate, result, host);
62e76326 415
b67e2c8c 416 return result;
59715b38 417}
418
419void
b67e2c8c 420ClassCBucket::initHostIndex (DelaySpec &rate, unsigned char index, unsigned char host)
59715b38 421{
b67e2c8c 422 assert (!individualUsed(index));
62e76326 423
b67e2c8c 424 unsigned char const newIndex = individuals.insert (host);
425
426 /* give the bucket a default value */
427 individuals.values[newIndex].init (rate);
428}
429
430void *
431CompositePoolNode::operator new(size_t size)
432{
433 DelayPools::MemoryUsed += sizeof (CompositePoolNode);
434 return ::operator new (size);
b6a2f15e 435}
436
437void
b67e2c8c 438CompositePoolNode::operator delete (void *address)
b6a2f15e 439{
b67e2c8c 440 DelayPools::MemoryUsed -= sizeof (CompositePoolNode);
441 ::operator delete (address);
b6a2f15e 442}
443
b67e2c8c 444void *
445Aggregate::operator new(size_t size)
446{
447 DelayPools::MemoryUsed += sizeof (Aggregate);
448 return ::operator new (size);
59715b38 449}
450
451void
b67e2c8c 452Aggregate::operator delete (void *address)
59715b38 453{
b67e2c8c 454 DelayPools::MemoryUsed -= sizeof (Aggregate);
455 ::operator delete (address);
59715b38 456}
457
b67e2c8c 458Aggregate::Aggregate()
459{
460 theBucket.init (*rate());
461 DelayPools::registerForUpdates (this);
462}
463
464Aggregate::~Aggregate()
465{
466 DelayPools::deregisterForUpdates (this);
59715b38 467}
468
469void
b67e2c8c 470Aggregate::stats(StoreEntry * sentry)
59715b38 471{
b67e2c8c 472 rate()->stats (sentry, "Aggregate");
62e76326 473
b67e2c8c 474 if (rate()->restore_bps == -1)
62e76326 475 return;
476
b67e2c8c 477 storeAppendPrintf(sentry, "\t\tCurrent: ");
62e76326 478
b67e2c8c 479 theBucket.stats(sentry);
62e76326 480
b67e2c8c 481 storeAppendPrintf(sentry, "\n\n");
59715b38 482}
483
484void
b67e2c8c 485Aggregate::dump(StoreEntry *entry) const
59715b38 486{
b67e2c8c 487 rate()->dump (entry);
59715b38 488}
489
490void
b67e2c8c 491Aggregate::update(int incr)
59715b38 492{
b67e2c8c 493 theBucket.update(*rate(), incr);
a46d2c0e 494 kickReads();
447e176b 495}
95e36d02 496
b67e2c8c 497void
498Aggregate::parse()
59715b38 499{
b67e2c8c 500 rate()->parse();
59715b38 501}
502
b67e2c8c 503DelayIdComposite::Pointer
1e5562e3 504Aggregate::id(CompositeSelectionDetails &details)
59715b38 505{
b67e2c8c 506 if (rate()->restore_bps != -1)
62e76326 507 return new AggregateId (this);
b67e2c8c 508 else
62e76326 509 return new NullDelayId;
59715b38 510}
511
b67e2c8c 512void *
513Aggregate::AggregateId::operator new(size_t size)
95e36d02 514{
b67e2c8c 515 DelayPools::MemoryUsed += sizeof (AggregateId);
516 return ::operator new (size);
95e36d02 517}
518
b67e2c8c 519void
520Aggregate::AggregateId::operator delete (void *address)
521{
522 DelayPools::MemoryUsed -= sizeof (AggregateId);
523 ::operator delete (address);
95e36d02 524}
525
75566ba2 526Aggregate::AggregateId::AggregateId(RefCount<Aggregate> anAggregate) : theAggregate(anAggregate)
62e76326 527{}
95e36d02 528
447e176b 529int
b67e2c8c 530Aggregate::AggregateId::bytesWanted (int min, int max) const
447e176b 531{
b67e2c8c 532 return theAggregate->theBucket.bytesWanted(min, max);
533}
59715b38 534
b67e2c8c 535void
536Aggregate::AggregateId::bytesIn(int qty)
537{
538 theAggregate->theBucket.bytesIn(qty);
a46d2c0e 539 theAggregate->kickReads();
b67e2c8c 540}
447e176b 541
b67e2c8c 542DelayPool *DelayPools::delay_data = NULL;
b67e2c8c 543time_t DelayPools::LastUpdate = 0;
544unsigned short DelayPools::pools_ (0);
447e176b 545
b67e2c8c 546void
6b7d87bb 547DelayPools::RegisterWithCacheManager(void)
b67e2c8c 548{
8822ebee 549 Mgr::RegisterAction("delay", "Delay Pool Levels", Stats, 0, 1);
62ee09ca 550}
551
552void
6b7d87bb 553DelayPools::Init()
62ee09ca 554{
6b7d87bb
FC
555 LastUpdate = getCurrentTime();
556 RegisterWithCacheManager();
b67e2c8c 557}
447e176b 558
6b7d87bb 559
b67e2c8c 560void
561DelayPools::InitDelayData()
562{
563 if (!pools())
62e76326 564 return;
565
b67e2c8c 566 DelayPools::delay_data = new DelayPool[pools()];
62e76326 567
b67e2c8c 568 DelayPools::MemoryUsed += pools() * sizeof(DelayPool);
62e76326 569
b67e2c8c 570 eventAdd("DelayPools::Update", DelayPools::Update, NULL, 1.0, 1);
571}
447e176b 572
b67e2c8c 573void
574DelayPools::FreeDelayData()
575{
dbdd8f13 576 eventDelete(DelayPools::Update, NULL);
b67e2c8c 577 delete[] DelayPools::delay_data;
578 DelayPools::MemoryUsed -= pools() * sizeof(*DelayPools::delay_data);
579 pools_ = 0;
447e176b 580}
581
b67e2c8c 582void
583DelayPools::Update(void *unused)
584{
585 if (!pools())
62e76326 586 return;
587
b67e2c8c 588 eventAdd("DelayPools::Update", Update, NULL, 1.0, 1);
62e76326 589
b67e2c8c 590 int incr = squid_curtime - LastUpdate;
62e76326 591
b67e2c8c 592 if (incr < 1)
62e76326 593 return;
594
b67e2c8c 595 LastUpdate = squid_curtime;
62e76326 596
b67e2c8c 597 Vector<Updateable *>::iterator pos = toUpdate.begin();
62e76326 598
b67e2c8c 599 while (pos != toUpdate.end()) {
62e76326 600 (*pos)->update(incr);
601 ++pos;
447e176b 602 }
447e176b 603}
604
b67e2c8c 605void
606DelayPools::registerForUpdates(Updateable *anObject)
607{
608 /* Assume no doubles */
609 toUpdate.push_back(anObject);
610}
611
612void
613DelayPools::deregisterForUpdates (Updateable *anObject)
614{
615 Vector<Updateable *>::iterator pos = toUpdate.begin();
62e76326 616
b67e2c8c 617 while (pos != toUpdate.end() && *pos != anObject) {
62e76326 618 ++pos;
447e176b 619 }
62e76326 620
b67e2c8c 621 if (pos != toUpdate.end()) {
62e76326 622 /* move all objects down one */
623 Vector<Updateable *>::iterator temp = pos;
624 ++pos;
625
626 while (pos != toUpdate.end()) {
627 *temp = *pos;
628 ++temp;
629 ++pos;
630 }
631
632 toUpdate.pop_back();
447e176b 633 }
447e176b 634}
635
b67e2c8c 636Vector<Updateable *> DelayPools::toUpdate;
637
447e176b 638void
b67e2c8c 639DelayPools::Stats(StoreEntry * sentry)
447e176b 640{
b67e2c8c 641 unsigned short i;
642
643 storeAppendPrintf(sentry, "Delay pools configured: %d\n\n", DelayPools::pools());
62e76326 644
b67e2c8c 645 for (i = 0; i < DelayPools::pools(); ++i) {
62e76326 646 if (DelayPools::delay_data[i].theComposite().getRaw()) {
647 storeAppendPrintf(sentry, "Pool: %d\n\tClass: %s\n\n", i + 1, DelayPools::delay_data[i].pool->theClassTypeLabel());
648 DelayPools::delay_data[i].theComposite()->stats (sentry);
649 } else
650 storeAppendPrintf(sentry, "\tMisconfigured pool.\n\n");
b67e2c8c 651 }
62e76326 652
b67e2c8c 653 storeAppendPrintf(sentry, "Memory Used: %d bytes\n", (int) DelayPools::MemoryUsed);
447e176b 654}
655
b67e2c8c 656void
657DelayPools::FreePools()
59715b38 658{
b67e2c8c 659 if (!DelayPools::pools())
62e76326 660 return;
661
b67e2c8c 662 FreeDelayData();
663}
664
665unsigned short
62e76326 666DelayPools::pools()
b67e2c8c 667{
668 return pools_;
669}
670
671void
f45dd259 672DelayPools::pools(unsigned short newPools)
b67e2c8c 673{
674 if (pools()) {
bf8fe701 675 debugs(3, 0, "parse_delay_pool_count: multiple delay_pools lines, aborting all previous delay_pools config");
62e76326 676 FreePools();
59715b38 677 }
62e76326 678
b67e2c8c 679 pools_ = newPools;
62e76326 680
b67e2c8c 681 if (pools())
62e76326 682 InitDelayData();
b67e2c8c 683}
684
685template <class Key, class Value>
686VectorMap<Key,Value>::VectorMap() : nextMapPosition(0)
62e76326 687{}
b67e2c8c 688
689template <class Key, class Value>
62e76326 690unsigned int
b67e2c8c 691VectorMap<Key,Value>::size() const
692{
693 return nextMapPosition;
694}
62e76326 695
b67e2c8c 696template <class Key, class Value>
697unsigned int
698VectorMap<Key,Value>::insert (Key const key)
699{
700 unsigned char index = findKeyIndex (key);
701 assert (!indexUsed(index));
702
703 key_map[index] = key;
704
705 ++nextMapPosition;
706
707 return index;
708}
709
710void *
711IndividualPool::operator new(size_t size)
712{
713 DelayPools::MemoryUsed += sizeof (IndividualPool);
714 return ::operator new (size);
715}
716
717void
718IndividualPool::operator delete (void *address)
719{
720 DelayPools::MemoryUsed -= sizeof (IndividualPool);
721 ::operator delete (address);
59715b38 722}
723
b67e2c8c 724VectorPool::VectorPool()
725{
726 DelayPools::registerForUpdates (this);
59715b38 727}
728
b67e2c8c 729VectorPool::~VectorPool()
59715b38 730{
b67e2c8c 731 DelayPools::deregisterForUpdates (this);
732}
59715b38 733
b67e2c8c 734void
735VectorPool::stats(StoreEntry * sentry)
736{
737 rate()->stats (sentry, label());
62e76326 738
b67e2c8c 739 if (rate()->restore_bps == -1) {
62e76326 740 storeAppendPrintf(sentry, "\n\n");
741 return;
59715b38 742 }
62e76326 743
b67e2c8c 744 storeAppendPrintf(sentry, "\t\tCurrent:");
62e76326 745
b67e2c8c 746 for (unsigned int i = 0; i < buckets.size(); i++) {
62e76326 747 storeAppendPrintf(sentry, " %d:", buckets.key_map[i]);
748 buckets.values[i].stats(sentry);
59715b38 749 }
62e76326 750
b67e2c8c 751 if (!buckets.size())
62e76326 752 storeAppendPrintf(sentry, " Not used yet.");
753
59715b38 754 storeAppendPrintf(sentry, "\n\n");
755}
756
b67e2c8c 757void
758VectorPool::dump(StoreEntry *entry) const
759{
760 rate()->dump (entry);
761}
762
763void
764VectorPool::update(int incr)
765{
766 if (rate()->restore_bps == -1)
62e76326 767 return;
768
b67e2c8c 769 for (unsigned int i = 0; i< buckets.size(); ++i)
62e76326 770 buckets.values[i].update (*rate(), incr);
b67e2c8c 771}
772
773void
774VectorPool::parse()
775{
776 rate()->parse();
777}
778
779bool
780VectorPool::keyAllocated (unsigned char const key) const
781{
782 return buckets.indexUsed(buckets.findKeyIndex (key));
783}
784
785template <class Key, class Value>
786bool
787VectorMap<Key,Value>::indexUsed (unsigned char const index) const
788{
b67e2c8c 789 return index < size();
790}
791
63be0a78 792/** returns the used position, or the position to allocate */
b67e2c8c 793template <class Key, class Value>
794unsigned char
795VectorMap<Key,Value>::findKeyIndex (Key const key) const
796{
797 for (unsigned int index = 0; index < size(); ++index) {
b1fb3348 798 assert(indexUsed(index));
62e76326 799
800 if (key_map[index] == key)
801 return index;
59715b38 802 }
62e76326 803
b67e2c8c 804 /* not in map */
805 return size();
806}
807
808DelayIdComposite::Pointer
1e5562e3 809VectorPool::id(CompositeSelectionDetails &details)
b67e2c8c 810{
811 if (rate()->restore_bps == -1)
62e76326 812 return new NullDelayId;
b67e2c8c 813
b1fb3348
AJ
814 /* non-IPv4 are not able to provide IPv4-bitmask for this pool type key. */
815 if ( !details.src_addr.IsIPv4() )
816 return new NullDelayId;
b67e2c8c 817
b1fb3348
AJ
818 unsigned int key = makeKey(details.src_addr);
819
820 if (keyAllocated(key))
821 return new Id(this, buckets.findKeyIndex(key));
62e76326 822
b67e2c8c 823 unsigned char const resultIndex = buckets.insert(key);
62e76326 824
b1fb3348 825 buckets.values[resultIndex].init(*rate());
62e76326 826
b67e2c8c 827 return new Id(this, resultIndex);
828}
829
830void *
831VectorPool::Id::operator new(size_t size)
832{
833 DelayPools::MemoryUsed += sizeof (Id);
834 return ::operator new (size);
835}
836
837void
b1fb3348 838VectorPool::Id::operator delete(void *address)
b67e2c8c 839{
840 DelayPools::MemoryUsed -= sizeof (Id);
841 ::operator delete (address);
842}
843
b1fb3348 844VectorPool::Id::Id(VectorPool::Pointer aPool, int anIndex) : theVector (aPool), theIndex (anIndex)
62e76326 845{}
b67e2c8c 846
847int
848VectorPool::Id::bytesWanted (int min, int max) const
849{
850 return theVector->buckets.values[theIndex].bytesWanted (min, max);
851}
852
853void
854VectorPool::Id::bytesIn(int qty)
855{
856 theVector->buckets.values[theIndex].bytesIn (qty);
857}
858
871899ca 859unsigned int
b7ac5457 860IndividualPool::makeKey(Ip::Address &src_addr) const
b67e2c8c 861{
b1fb3348 862 /* IPv4 required for this pool */
26ac0430 863 if ( !src_addr.IsIPv4() )
cc192b50 864 return 1;
865
cc192b50 866 struct in_addr host;
867 src_addr.GetInAddr(host);
868 return (ntohl(host.s_addr) & 0xff);
b67e2c8c 869}
870
871void *
872ClassCNetPool::operator new(size_t size)
873{
874 DelayPools::MemoryUsed += sizeof (ClassCNetPool);
875 return ::operator new (size);
876}
877
878void
879ClassCNetPool::operator delete (void *address)
880{
881 DelayPools::MemoryUsed -= sizeof (ClassCNetPool);
882 ::operator delete (address);
883}
884
871899ca 885unsigned int
b7ac5457 886ClassCNetPool::makeKey(Ip::Address &src_addr) const
b67e2c8c 887{
b1fb3348 888 /* IPv4 required for this pool */
26ac0430 889 if ( !src_addr.IsIPv4() )
cc192b50 890 return 1;
891
cc192b50 892 struct in_addr net;
893 src_addr.GetInAddr(net);
894 return ( (ntohl(net.s_addr) >> 8) & 0xff);
b67e2c8c 895}
896
897
898ClassCHostPool::ClassCHostPool()
899{
900 DelayPools::registerForUpdates (this);
901}
902
903ClassCHostPool::~ClassCHostPool()
904{
905 DelayPools::deregisterForUpdates (this);
906}
907
908void
909ClassCHostPool::stats(StoreEntry * sentry)
910{
911 rate()->stats (sentry, label());
62e76326 912
b67e2c8c 913 if (rate()->restore_bps == -1) {
62e76326 914 storeAppendPrintf(sentry, "\n\n");
915 return;
59715b38 916 }
b67e2c8c 917
918 for (unsigned int index = 0; index < buckets.size(); ++index) {
62e76326 919 storeAppendPrintf(sentry, "\t\tCurrent [Network %d]:", buckets.key_map[index]);
920 buckets.values[index].stats (sentry);
921 storeAppendPrintf(sentry, "\n");
59715b38 922 }
b67e2c8c 923
924 if (!buckets.size())
62e76326 925 storeAppendPrintf(sentry, "\t\tCurrent [All networks]: Not used yet.\n");
b67e2c8c 926
927 storeAppendPrintf(sentry, "\n\n");
59715b38 928}
929
b67e2c8c 930void
931ClassCHostPool::dump(StoreEntry *entry) const
59715b38 932{
b67e2c8c 933 rate()->dump (entry);
934}
59715b38 935
b67e2c8c 936void
937ClassCHostPool::update(int incr)
938{
939 if (rate()->restore_bps == -1)
62e76326 940 return;
941
b67e2c8c 942 for (unsigned int i = 0; i< buckets.size(); ++i)
62e76326 943 buckets.values[i].update (*rate(), incr);
b67e2c8c 944}
945
946void
947ClassCHostPool::parse()
948{
949 rate()->parse();
950}
951
952bool
953ClassCHostPool::keyAllocated (unsigned char const key) const
954{
955 return buckets.indexUsed(buckets.findKeyIndex (key));
956}
957
871899ca 958unsigned char
b7ac5457 959ClassCHostPool::makeHostKey(Ip::Address &src_addr) const
b67e2c8c 960{
b1fb3348 961 /* IPv4 required for this pool */
26ac0430 962 if ( !src_addr.IsIPv4() )
cc192b50 963 return 1;
964
965 /* Temporary bypass for IPv4-only */
966 struct in_addr host;
967 src_addr.GetInAddr(host);
968 return (ntohl(host.s_addr) & 0xff);
b67e2c8c 969}
970
871899ca 971unsigned int
b7ac5457 972ClassCHostPool::makeKey(Ip::Address &src_addr) const
b67e2c8c 973{
b1fb3348 974 /* IPv4 required for this pool */
26ac0430 975 if ( !src_addr.IsIPv4() )
cc192b50 976 return 1;
977
cc192b50 978 struct in_addr net;
979 src_addr.GetInAddr(net);
980 return ( (ntohl(net.s_addr) >> 8) & 0xff);
b67e2c8c 981}
62e76326 982
b67e2c8c 983DelayIdComposite::Pointer
1e5562e3 984ClassCHostPool::id(CompositeSelectionDetails &details)
b67e2c8c 985{
986 if (rate()->restore_bps == -1)
62e76326 987 return new NullDelayId;
b67e2c8c 988
b1fb3348
AJ
989 /* non-IPv4 are not able to provide IPv4-bitmask for this pool type key. */
990 if ( !details.src_addr.IsIPv4() )
991 return new NullDelayId;
992
1e5562e3 993 unsigned int key = makeKey (details.src_addr);
62e76326 994
1e5562e3 995 unsigned char host = makeHostKey (details.src_addr);
b67e2c8c 996
997 unsigned char hostIndex;
62e76326 998
b67e2c8c 999 unsigned char netIndex;
62e76326 1000
b67e2c8c 1001 if (keyAllocated (key))
62e76326 1002 netIndex = buckets.findKeyIndex(key);
b67e2c8c 1003 else
62e76326 1004 netIndex = buckets.insert (key);
b67e2c8c 1005
1006 hostIndex = buckets.values[netIndex].hostPosition (*rate(), host);
62e76326 1007
b67e2c8c 1008 return new Id (this, netIndex, hostIndex);
1009}
1010
1011void *
1012ClassCHostPool::Id::operator new(size_t size)
1013{
1014 DelayPools::MemoryUsed += sizeof (Id);
1015 return ::operator new (size);
1016}
1017
1018void
1019ClassCHostPool::Id::operator delete (void *address)
1020{
1021 DelayPools::MemoryUsed -= sizeof (Id);
1022 ::operator delete (address);
1023}
1024
b67e2c8c 1025ClassCHostPool::Id::Id (ClassCHostPool::Pointer aPool, unsigned char aNet, unsigned char aHost) : theClassCHost (aPool), theNet (aNet), theHost (aHost)
62e76326 1026{}
b67e2c8c 1027
1028int
1029ClassCHostPool::Id::bytesWanted (int min, int max) const
1030{
1031 return theClassCHost->buckets.values[theNet].individuals.values[theHost].bytesWanted (min, max);
1032}
1033
1034void
1035ClassCHostPool::Id::bytesIn(int qty)
1036{
1037 theClassCHost->buckets.values[theNet].individuals.values[theHost].bytesIn (qty);
59715b38 1038}
1039
9a0a18de 1040#endif /* USE_DELAY_POOLS */