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