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