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