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