2 * DEBUG: section 77 Delay Pools
3 * AUTHOR: Robert Collins <robertc@squid-cache.org>
4 * Based upon original delay pools code by
5 * David Luyer <david@luyer.net>
7 * SQUID Web Proxy Cache http://www.squid-cache.org/
8 * ----------------------------------------------------------
10 * Squid is the result of efforts by numerous individuals from
11 * the Internet community; see the CONTRIBUTORS file for full
12 * details. Many organizations have provided support for Squid's
13 * development; see the SPONSORS file for full details. Squid is
14 * Copyrighted (C) 2001 by the Regents of the University of
15 * California; see the COPYRIGHT file for full details. Squid
16 * incorporates software developed and/or copyrighted by other
17 * sources; see the CREDITS file for full details.
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
34 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
38 \defgroup DelayPoolsInternal Delay Pools Internal
39 \ingroup DelayPoolsAPI
45 #include "client_side_request.h"
46 #include "comm/Connection.h"
47 #include "CommonPool.h"
48 #include "CompositePoolNode.h"
49 #include "ConfigParser.h"
50 #include "DelayBucket.h"
52 #include "DelayPool.h"
53 #include "DelayPools.h"
54 #include "DelaySpec.h"
55 #include "DelayTagged.h"
56 #include "DelayUser.h"
57 #include "DelayVector.h"
59 #include "ip/Address.h"
60 #include "MemObject.h"
61 #include "mgr/Registration.h"
62 #include "NullDelayId.h"
63 #include "SquidString.h"
64 #include "SquidTime.h"
66 #include "StoreClient.h"
68 /// \ingroup DelayPoolsInternal
69 long DelayPools::MemoryUsed
= 0;
71 /// \ingroup DelayPoolsInternal
72 class Aggregate
: public CompositePoolNode
76 typedef RefCount
<Aggregate
> Pointer
;
77 void *operator new(size_t);
78 void operator delete (void *);
81 virtual DelaySpec
*rate() {return &spec
;}
83 virtual DelaySpec
const *rate() const {return &spec
;}
85 virtual void stats(StoreEntry
* sentry
);
86 virtual void dump(StoreEntry
*entry
) const;
87 virtual void update(int incr
);
90 virtual DelayIdComposite::Pointer
id(CompositeSelectionDetails
&);
94 /// \ingroup DelayPoolsInternal
95 class AggregateId
:public DelayIdComposite
99 void *operator new(size_t);
100 void operator delete (void *);
101 AggregateId (RefCount
<Aggregate
>);
102 virtual int bytesWanted (int min
, int max
) const;
103 virtual void bytesIn(int qty
);
104 virtual void delayRead(DeferredRead
const &);
107 RefCount
<Aggregate
> theAggregate
;
110 friend class AggregateId
;
112 DelayBucket theBucket
;
116 /// \ingroup DelayPoolsInternal
117 template <class Key
, class Value
>
123 unsigned int size() const;
124 unsigned char findKeyIndex (Key
const key
) const;
125 bool indexUsed (unsigned char const index
) const;
126 unsigned int insert (Key
const key
);
128 #define IND_MAP_SZ 256
130 Key key_map
[IND_MAP_SZ
];
131 Value values
[IND_MAP_SZ
];
134 unsigned int nextMapPosition
;
137 /// \ingroup DelayPoolsInternal
138 class VectorPool
: public CompositePoolNode
142 typedef RefCount
<VectorPool
> Pointer
;
143 virtual void dump(StoreEntry
*entry
) const;
144 virtual void parse();
145 virtual void update(int incr
);
146 virtual void stats(StoreEntry
* sentry
);
148 virtual DelayIdComposite::Pointer
id(CompositeSelectionDetails
&);
149 VectorMap
<unsigned char, DelayBucket
> buckets
;
154 bool keyAllocated (unsigned char const key
) const;
155 virtual DelaySpec
*rate() {return &spec
;}
157 virtual DelaySpec
const *rate() const {return &spec
;}
159 virtual char const *label() const = 0;
161 virtual unsigned int makeKey(Ip::Address
&src_addr
) const = 0;
165 /// \ingroup DelayPoolsInternal
166 class Id
:public DelayIdComposite
170 void *operator new(size_t);
171 void operator delete (void *);
172 Id (RefCount
<VectorPool
>, int);
173 virtual int bytesWanted (int min
, int max
) const;
174 virtual void bytesIn(int qty
);
177 RefCount
<VectorPool
> theVector
;
182 /// \ingroup DelayPoolsInternal
183 class IndividualPool
: public VectorPool
187 void *operator new(size_t);
188 void operator delete(void *);
191 virtual char const *label() const {return "Individual";}
192 virtual unsigned int makeKey(Ip::Address
&src_addr
) const;
195 /// \ingroup DelayPoolsInternal
196 class ClassCNetPool
: public VectorPool
200 void *operator new(size_t);
201 void operator delete (void *);
204 virtual char const *label() const {return "Network";}
205 virtual unsigned int makeKey (Ip::Address
&src_addr
) const;
208 /* don't use remote storage for these */
209 /// \ingroup DelayPoolsInternal
214 bool individualUsed (unsigned int index
)const;
215 unsigned char findHostMapPosition (unsigned char const host
) const;
216 bool individualAllocated (unsigned char host
) const;
217 unsigned char hostPosition (DelaySpec
&rate
, unsigned char const host
);
218 void initHostIndex (DelaySpec
&rate
, unsigned char index
, unsigned char host
);
219 void update (DelaySpec
const &, int incr
);
220 void stats(StoreEntry
*)const;
223 VectorMap
<unsigned char, DelayBucket
> individuals
;
226 /// \ingroup DelayPoolsInternal
227 class ClassCHostPool
: public CompositePoolNode
231 typedef RefCount
<ClassCHostPool
> Pointer
;
232 virtual void dump(StoreEntry
*entry
) const;
233 virtual void parse();
234 virtual void update(int incr
);
235 virtual void stats(StoreEntry
* sentry
);
237 virtual DelayIdComposite::Pointer
id(CompositeSelectionDetails
&);
242 bool keyAllocated (unsigned char const key
) const;
243 virtual DelaySpec
*rate() {return &spec
;}
245 virtual DelaySpec
const *rate() const {return &spec
;}
247 virtual char const *label() const {return "Individual";}
249 virtual unsigned int makeKey(Ip::Address
&src_addr
) const;
251 unsigned char makeHostKey(Ip::Address
&src_addr
) const;
254 VectorMap
<unsigned char, ClassCBucket
> buckets
;
258 friend class ClassCHostPool::Id
;
260 /// \ingroup DelayPoolsInternal
261 class Id
:public DelayIdComposite
265 void *operator new(size_t);
266 void operator delete (void *);
267 Id (RefCount
<ClassCHostPool
>, unsigned char, unsigned char);
268 virtual int bytesWanted (int min
, int max
) const;
269 virtual void bytesIn(int qty
);
272 RefCount
<ClassCHostPool
> theClassCHost
;
273 unsigned char theNet
;
274 unsigned char theHost
;
279 Aggregate::AggregateId::delayRead(DeferredRead
const &aRead
)
281 theAggregate
->delayRead(aRead
);
285 CommonPool::operator new(size_t size
)
287 DelayPools::MemoryUsed
+= sizeof (CommonPool
);
288 return ::operator new (size
);
292 CommonPool::operator delete(void *address
)
294 DelayPools::MemoryUsed
-= sizeof(CommonPool
);
295 ::operator delete(address
);
299 CommonPool::Factory(unsigned char _class
, CompositePoolNode::Pointer
& compositeCopy
)
301 CommonPool
*result
= new CommonPool
;
309 compositeCopy
= new Aggregate
;
310 result
->typeLabel
= "1";
314 result
->typeLabel
= "2";
316 DelayVector::Pointer temp
= new DelayVector
;
317 compositeCopy
= temp
.getRaw();
318 temp
->push_back (new Aggregate
);
319 temp
->push_back(new IndividualPool
);
324 result
->typeLabel
= "3";
326 DelayVector::Pointer temp
= new DelayVector
;
327 compositeCopy
= temp
.getRaw();
328 temp
->push_back (new Aggregate
);
329 temp
->push_back (new ClassCNetPool
);
330 temp
->push_back (new ClassCHostPool
);
335 result
->typeLabel
= "4";
337 DelayVector::Pointer temp
= new DelayVector
;
338 compositeCopy
= temp
.getRaw();
339 temp
->push_back (new Aggregate
);
340 temp
->push_back (new ClassCNetPool
);
341 temp
->push_back (new ClassCHostPool
);
343 temp
->push_back (new DelayUser
);
349 result
->typeLabel
= "5";
350 compositeCopy
= new DelayTagged
;
354 fatal ("unknown delay pool class");
361 CommonPool::CommonPool()
365 ClassCBucket::update (DelaySpec
const &rate
, int incr
)
367 /* If we aren't active, don't try to update us ! */
368 assert (rate
.restore_bps
!= -1);
370 for (unsigned int j
= 0; j
< individuals
.size(); ++j
)
371 individuals
.values
[j
].update (rate
, incr
);
375 ClassCBucket::stats(StoreEntry
*sentry
)const
377 for (unsigned int j
= 0; j
< individuals
.size(); ++j
) {
378 assert (individualUsed (j
));
379 storeAppendPrintf(sentry
, " %d:",individuals
.key_map
[j
]);
380 individuals
.values
[j
].stats (sentry
);
385 ClassCBucket::findHostMapPosition (unsigned char const host
) const
387 return individuals
.findKeyIndex(host
);
391 ClassCBucket::individualUsed (unsigned int index
)const
393 return individuals
.indexUsed(index
);
397 ClassCBucket::individualAllocated (unsigned char host
) const
399 return individualUsed(findHostMapPosition (host
));
403 ClassCBucket::hostPosition (DelaySpec
&rate
, unsigned char const host
)
405 if (individualAllocated (host
))
406 return findHostMapPosition(host
);
408 assert (!individualUsed (findHostMapPosition(host
)));
410 unsigned char result
= findHostMapPosition(host
);
412 initHostIndex (rate
, result
, host
);
418 ClassCBucket::initHostIndex (DelaySpec
&rate
, unsigned char index
, unsigned char host
)
420 assert (!individualUsed(index
));
422 unsigned char const newIndex
= individuals
.insert (host
);
424 /* give the bucket a default value */
425 individuals
.values
[newIndex
].init (rate
);
429 CompositePoolNode::operator new(size_t size
)
431 DelayPools::MemoryUsed
+= sizeof (CompositePoolNode
);
432 return ::operator new (size
);
436 CompositePoolNode::operator delete (void *address
)
438 DelayPools::MemoryUsed
-= sizeof (CompositePoolNode
);
439 ::operator delete (address
);
443 Aggregate::operator new(size_t size
)
445 DelayPools::MemoryUsed
+= sizeof (Aggregate
);
446 return ::operator new (size
);
450 Aggregate::operator delete (void *address
)
452 DelayPools::MemoryUsed
-= sizeof (Aggregate
);
453 ::operator delete (address
);
456 Aggregate::Aggregate()
458 theBucket
.init (*rate());
459 DelayPools::registerForUpdates (this);
462 Aggregate::~Aggregate()
464 DelayPools::deregisterForUpdates (this);
468 Aggregate::stats(StoreEntry
* sentry
)
470 rate()->stats (sentry
, "Aggregate");
472 if (rate()->restore_bps
== -1)
475 storeAppendPrintf(sentry
, "\t\tCurrent: ");
477 theBucket
.stats(sentry
);
479 storeAppendPrintf(sentry
, "\n\n");
483 Aggregate::dump(StoreEntry
*entry
) const
485 rate()->dump (entry
);
489 Aggregate::update(int incr
)
491 theBucket
.update(*rate(), incr
);
501 DelayIdComposite::Pointer
502 Aggregate::id(CompositeSelectionDetails
&details
)
504 if (rate()->restore_bps
!= -1)
505 return new AggregateId (this);
507 return new NullDelayId
;
511 Aggregate::AggregateId::operator new(size_t size
)
513 DelayPools::MemoryUsed
+= sizeof (AggregateId
);
514 return ::operator new (size
);
518 Aggregate::AggregateId::operator delete (void *address
)
520 DelayPools::MemoryUsed
-= sizeof (AggregateId
);
521 ::operator delete (address
);
524 Aggregate::AggregateId::AggregateId(RefCount
<Aggregate
> anAggregate
) : theAggregate(anAggregate
)
528 Aggregate::AggregateId::bytesWanted (int min
, int max
) const
530 return theAggregate
->theBucket
.bytesWanted(min
, max
);
534 Aggregate::AggregateId::bytesIn(int qty
)
536 theAggregate
->theBucket
.bytesIn(qty
);
537 theAggregate
->kickReads();
540 DelayPool
*DelayPools::delay_data
= NULL
;
541 time_t DelayPools::LastUpdate
= 0;
542 unsigned short DelayPools::pools_ (0);
545 DelayPools::RegisterWithCacheManager(void)
547 Mgr::RegisterAction("delay", "Delay Pool Levels", Stats
, 0, 1);
553 LastUpdate
= getCurrentTime();
554 RegisterWithCacheManager();
558 DelayPools::InitDelayData()
563 DelayPools::delay_data
= new DelayPool
[pools()];
565 DelayPools::MemoryUsed
+= pools() * sizeof(DelayPool
);
567 eventAdd("DelayPools::Update", DelayPools::Update
, NULL
, 1.0, 1);
571 DelayPools::FreeDelayData()
573 eventDelete(DelayPools::Update
, NULL
);
574 delete[] DelayPools::delay_data
;
575 DelayPools::MemoryUsed
-= pools() * sizeof(*DelayPools::delay_data
);
580 DelayPools::Update(void *unused
)
585 eventAdd("DelayPools::Update", Update
, NULL
, 1.0, 1);
587 int incr
= squid_curtime
- LastUpdate
;
592 LastUpdate
= squid_curtime
;
594 std::vector
<Updateable
*>::iterator pos
= toUpdate
.begin();
596 while (pos
!= toUpdate
.end()) {
597 (*pos
)->update(incr
);
603 DelayPools::registerForUpdates(Updateable
*anObject
)
605 /* Assume no doubles */
606 toUpdate
.push_back(anObject
);
610 DelayPools::deregisterForUpdates (Updateable
*anObject
)
612 std::vector
<Updateable
*>::iterator pos
= toUpdate
.begin();
614 while (pos
!= toUpdate
.end() && *pos
!= anObject
) {
618 if (pos
!= toUpdate
.end()) {
619 /* move all objects down one */
620 std::vector
<Updateable
*>::iterator temp
= pos
;
623 while (pos
!= toUpdate
.end()) {
633 std::vector
<Updateable
*> DelayPools::toUpdate
;
636 DelayPools::Stats(StoreEntry
* sentry
)
640 storeAppendPrintf(sentry
, "Delay pools configured: %d\n\n", DelayPools::pools());
642 for (i
= 0; i
< DelayPools::pools(); ++i
) {
643 if (DelayPools::delay_data
[i
].theComposite().getRaw()) {
644 storeAppendPrintf(sentry
, "Pool: %d\n\tClass: %s\n\n", i
+ 1, DelayPools::delay_data
[i
].pool
->theClassTypeLabel());
645 DelayPools::delay_data
[i
].theComposite()->stats (sentry
);
647 storeAppendPrintf(sentry
, "\tMisconfigured pool.\n\n");
650 storeAppendPrintf(sentry
, "Memory Used: %d bytes\n", (int) DelayPools::MemoryUsed
);
654 DelayPools::FreePools()
656 if (!DelayPools::pools())
669 DelayPools::pools(unsigned short newPools
)
672 debugs(3, DBG_CRITICAL
, "parse_delay_pool_count: multiple delay_pools lines, aborting all previous delay_pools config");
682 template <class Key
, class Value
>
683 VectorMap
<Key
,Value
>::VectorMap() : nextMapPosition(0)
686 template <class Key
, class Value
>
688 VectorMap
<Key
,Value
>::size() const
690 return nextMapPosition
;
693 template <class Key
, class Value
>
695 VectorMap
<Key
,Value
>::insert (Key
const key
)
697 unsigned char index
= findKeyIndex (key
);
698 assert (!indexUsed(index
));
700 key_map
[index
] = key
;
708 IndividualPool::operator new(size_t size
)
710 DelayPools::MemoryUsed
+= sizeof (IndividualPool
);
711 return ::operator new (size
);
715 IndividualPool::operator delete (void *address
)
717 DelayPools::MemoryUsed
-= sizeof (IndividualPool
);
718 ::operator delete (address
);
721 VectorPool::VectorPool()
723 DelayPools::registerForUpdates (this);
726 VectorPool::~VectorPool()
728 DelayPools::deregisterForUpdates (this);
732 VectorPool::stats(StoreEntry
* sentry
)
734 rate()->stats (sentry
, label());
736 if (rate()->restore_bps
== -1) {
737 storeAppendPrintf(sentry
, "\n\n");
741 storeAppendPrintf(sentry
, "\t\tCurrent:");
743 for (unsigned int i
= 0; i
< buckets
.size(); ++i
) {
744 storeAppendPrintf(sentry
, " %d:", buckets
.key_map
[i
]);
745 buckets
.values
[i
].stats(sentry
);
749 storeAppendPrintf(sentry
, " Not used yet.");
751 storeAppendPrintf(sentry
, "\n\n");
755 VectorPool::dump(StoreEntry
*entry
) const
757 rate()->dump (entry
);
761 VectorPool::update(int incr
)
763 if (rate()->restore_bps
== -1)
766 for (unsigned int i
= 0; i
< buckets
.size(); ++i
)
767 buckets
.values
[i
].update (*rate(), incr
);
777 VectorPool::keyAllocated (unsigned char const key
) const
779 return buckets
.indexUsed(buckets
.findKeyIndex (key
));
782 template <class Key
, class Value
>
784 VectorMap
<Key
,Value
>::indexUsed (unsigned char const index
) const
786 return index
< size();
789 /** returns the used position, or the position to allocate */
790 template <class Key
, class Value
>
792 VectorMap
<Key
,Value
>::findKeyIndex (Key
const key
) const
794 for (unsigned int index
= 0; index
< size(); ++index
) {
795 assert(indexUsed(index
));
797 if (key_map
[index
] == key
)
805 DelayIdComposite::Pointer
806 VectorPool::id(CompositeSelectionDetails
&details
)
808 if (rate()->restore_bps
== -1)
809 return new NullDelayId
;
811 /* non-IPv4 are not able to provide IPv4-bitmask for this pool type key. */
812 if ( !details
.src_addr
.isIPv4() )
813 return new NullDelayId
;
815 unsigned int key
= makeKey(details
.src_addr
);
817 if (keyAllocated(key
))
818 return new Id(this, buckets
.findKeyIndex(key
));
820 unsigned char const resultIndex
= buckets
.insert(key
);
822 buckets
.values
[resultIndex
].init(*rate());
824 return new Id(this, resultIndex
);
828 VectorPool::Id::operator new(size_t size
)
830 DelayPools::MemoryUsed
+= sizeof (Id
);
831 return ::operator new (size
);
835 VectorPool::Id::operator delete(void *address
)
837 DelayPools::MemoryUsed
-= sizeof (Id
);
838 ::operator delete (address
);
841 VectorPool::Id::Id(VectorPool::Pointer aPool
, int anIndex
) : theVector (aPool
), theIndex (anIndex
)
845 VectorPool::Id::bytesWanted (int min
, int max
) const
847 return theVector
->buckets
.values
[theIndex
].bytesWanted (min
, max
);
851 VectorPool::Id::bytesIn(int qty
)
853 theVector
->buckets
.values
[theIndex
].bytesIn (qty
);
857 IndividualPool::makeKey(Ip::Address
&src_addr
) const
859 /* IPv4 required for this pool */
860 if ( !src_addr
.isIPv4() )
864 src_addr
.getInAddr(host
);
865 return (ntohl(host
.s_addr
) & 0xff);
869 ClassCNetPool::operator new(size_t size
)
871 DelayPools::MemoryUsed
+= sizeof (ClassCNetPool
);
872 return ::operator new (size
);
876 ClassCNetPool::operator delete (void *address
)
878 DelayPools::MemoryUsed
-= sizeof (ClassCNetPool
);
879 ::operator delete (address
);
883 ClassCNetPool::makeKey(Ip::Address
&src_addr
) const
885 /* IPv4 required for this pool */
886 if ( !src_addr
.isIPv4() )
890 src_addr
.getInAddr(net
);
891 return ( (ntohl(net
.s_addr
) >> 8) & 0xff);
894 ClassCHostPool::ClassCHostPool()
896 DelayPools::registerForUpdates (this);
899 ClassCHostPool::~ClassCHostPool()
901 DelayPools::deregisterForUpdates (this);
905 ClassCHostPool::stats(StoreEntry
* sentry
)
907 rate()->stats (sentry
, label());
909 if (rate()->restore_bps
== -1) {
910 storeAppendPrintf(sentry
, "\n\n");
914 for (unsigned int index
= 0; index
< buckets
.size(); ++index
) {
915 storeAppendPrintf(sentry
, "\t\tCurrent [Network %d]:", buckets
.key_map
[index
]);
916 buckets
.values
[index
].stats (sentry
);
917 storeAppendPrintf(sentry
, "\n");
921 storeAppendPrintf(sentry
, "\t\tCurrent [All networks]: Not used yet.\n");
923 storeAppendPrintf(sentry
, "\n\n");
927 ClassCHostPool::dump(StoreEntry
*entry
) const
929 rate()->dump (entry
);
933 ClassCHostPool::update(int incr
)
935 if (rate()->restore_bps
== -1)
938 for (unsigned int i
= 0; i
< buckets
.size(); ++i
)
939 buckets
.values
[i
].update (*rate(), incr
);
943 ClassCHostPool::parse()
949 ClassCHostPool::keyAllocated (unsigned char const key
) const
951 return buckets
.indexUsed(buckets
.findKeyIndex (key
));
955 ClassCHostPool::makeHostKey(Ip::Address
&src_addr
) const
957 /* IPv4 required for this pool */
958 if ( !src_addr
.isIPv4() )
961 /* Temporary bypass for IPv4-only */
963 src_addr
.getInAddr(host
);
964 return (ntohl(host
.s_addr
) & 0xff);
968 ClassCHostPool::makeKey(Ip::Address
&src_addr
) const
970 /* IPv4 required for this pool */
971 if ( !src_addr
.isIPv4() )
975 src_addr
.getInAddr(net
);
976 return ( (ntohl(net
.s_addr
) >> 8) & 0xff);
979 DelayIdComposite::Pointer
980 ClassCHostPool::id(CompositeSelectionDetails
&details
)
982 if (rate()->restore_bps
== -1)
983 return new NullDelayId
;
985 /* non-IPv4 are not able to provide IPv4-bitmask for this pool type key. */
986 if ( !details
.src_addr
.isIPv4() )
987 return new NullDelayId
;
989 unsigned int key
= makeKey (details
.src_addr
);
991 unsigned char host
= makeHostKey (details
.src_addr
);
993 unsigned char hostIndex
;
995 unsigned char netIndex
;
997 if (keyAllocated (key
))
998 netIndex
= buckets
.findKeyIndex(key
);
1000 netIndex
= buckets
.insert (key
);
1002 hostIndex
= buckets
.values
[netIndex
].hostPosition (*rate(), host
);
1004 return new Id (this, netIndex
, hostIndex
);
1008 ClassCHostPool::Id::operator new(size_t size
)
1010 DelayPools::MemoryUsed
+= sizeof (Id
);
1011 return ::operator new (size
);
1015 ClassCHostPool::Id::operator delete (void *address
)
1017 DelayPools::MemoryUsed
-= sizeof (Id
);
1018 ::operator delete (address
);
1021 ClassCHostPool::Id::Id (ClassCHostPool::Pointer aPool
, unsigned char aNet
, unsigned char aHost
) : theClassCHost (aPool
), theNet (aNet
), theHost (aHost
)
1025 ClassCHostPool::Id::bytesWanted (int min
, int max
) const
1027 return theClassCHost
->buckets
.values
[theNet
].individuals
.values
[theHost
].bytesWanted (min
, max
);
1031 ClassCHostPool::Id::bytesIn(int qty
)
1033 theClassCHost
->buckets
.values
[theNet
].individuals
.values
[theHost
].bytesIn (qty
);
1036 #endif /* USE_DELAY_POOLS */