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 "base/Vector.h"
46 #include "client_side_request.h"
47 #include "comm/Connection.h"
48 #include "CommonPool.h"
49 #include "CompositePoolNode.h"
50 #include "ConfigParser.h"
51 #include "DelayBucket.h"
53 #include "DelayPool.h"
54 #include "DelayPools.h"
55 #include "DelaySpec.h"
56 #include "DelayTagged.h"
57 #include "DelayUser.h"
58 #include "DelayVector.h"
60 #include "ip/Address.h"
61 #include "MemObject.h"
62 #include "mgr/Registration.h"
63 #include "NullDelayId.h"
64 #include "SquidString.h"
65 #include "SquidTime.h"
67 #include "StoreClient.h"
69 /// \ingroup DelayPoolsInternal
70 long DelayPools::MemoryUsed
= 0;
72 /// \ingroup DelayPoolsInternal
73 class Aggregate
: public CompositePoolNode
77 typedef RefCount
<Aggregate
> Pointer
;
78 void *operator new(size_t);
79 void operator delete (void *);
82 virtual DelaySpec
*rate() {return &spec
;}
84 virtual DelaySpec
const *rate() const {return &spec
;}
86 virtual void stats(StoreEntry
* sentry
);
87 virtual void dump(StoreEntry
*entry
) const;
88 virtual void update(int incr
);
91 virtual DelayIdComposite::Pointer
id(CompositeSelectionDetails
&);
95 /// \ingroup DelayPoolsInternal
96 class AggregateId
:public DelayIdComposite
100 void *operator new(size_t);
101 void operator delete (void *);
102 AggregateId (RefCount
<Aggregate
>);
103 virtual int bytesWanted (int min
, int max
) const;
104 virtual void bytesIn(int qty
);
105 virtual void delayRead(DeferredRead
const &);
108 RefCount
<Aggregate
> theAggregate
;
111 friend class AggregateId
;
113 DelayBucket theBucket
;
117 /// \ingroup DelayPoolsInternal
118 template <class Key
, class Value
>
124 unsigned int size() const;
125 unsigned char findKeyIndex (Key
const key
) const;
126 bool indexUsed (unsigned char const index
) const;
127 unsigned int insert (Key
const key
);
129 #define IND_MAP_SZ 256
131 Key key_map
[IND_MAP_SZ
];
132 Value values
[IND_MAP_SZ
];
135 unsigned int nextMapPosition
;
138 /// \ingroup DelayPoolsInternal
139 class VectorPool
: public CompositePoolNode
143 typedef RefCount
<VectorPool
> Pointer
;
144 virtual void dump(StoreEntry
*entry
) const;
145 virtual void parse();
146 virtual void update(int incr
);
147 virtual void stats(StoreEntry
* sentry
);
149 virtual DelayIdComposite::Pointer
id(CompositeSelectionDetails
&);
150 VectorMap
<unsigned char, DelayBucket
> buckets
;
155 bool keyAllocated (unsigned char const key
) const;
156 virtual DelaySpec
*rate() {return &spec
;}
158 virtual DelaySpec
const *rate() const {return &spec
;}
160 virtual char const *label() const = 0;
162 virtual unsigned int makeKey(Ip::Address
&src_addr
) const = 0;
166 /// \ingroup DelayPoolsInternal
167 class Id
:public DelayIdComposite
171 void *operator new(size_t);
172 void operator delete (void *);
173 Id (RefCount
<VectorPool
>, int);
174 virtual int bytesWanted (int min
, int max
) const;
175 virtual void bytesIn(int qty
);
178 RefCount
<VectorPool
> theVector
;
183 /// \ingroup DelayPoolsInternal
184 class IndividualPool
: public VectorPool
188 void *operator new(size_t);
189 void operator delete(void *);
192 virtual char const *label() const {return "Individual";}
193 virtual unsigned int makeKey(Ip::Address
&src_addr
) const;
196 /// \ingroup DelayPoolsInternal
197 class ClassCNetPool
: public VectorPool
201 void *operator new(size_t);
202 void operator delete (void *);
205 virtual char const *label() const {return "Network";}
206 virtual unsigned int makeKey (Ip::Address
&src_addr
) const;
209 /* don't use remote storage for these */
210 /// \ingroup DelayPoolsInternal
215 bool individualUsed (unsigned int index
)const;
216 unsigned char findHostMapPosition (unsigned char const host
) const;
217 bool individualAllocated (unsigned char host
) const;
218 unsigned char hostPosition (DelaySpec
&rate
, unsigned char const host
);
219 void initHostIndex (DelaySpec
&rate
, unsigned char index
, unsigned char host
);
220 void update (DelaySpec
const &, int incr
);
221 void stats(StoreEntry
*)const;
224 VectorMap
<unsigned char, DelayBucket
> individuals
;
227 /// \ingroup DelayPoolsInternal
228 class ClassCHostPool
: public CompositePoolNode
232 typedef RefCount
<ClassCHostPool
> Pointer
;
233 virtual void dump(StoreEntry
*entry
) const;
234 virtual void parse();
235 virtual void update(int incr
);
236 virtual void stats(StoreEntry
* sentry
);
238 virtual DelayIdComposite::Pointer
id(CompositeSelectionDetails
&);
243 bool keyAllocated (unsigned char const key
) const;
244 virtual DelaySpec
*rate() {return &spec
;}
246 virtual DelaySpec
const *rate() const {return &spec
;}
248 virtual char const *label() const {return "Individual";}
250 virtual unsigned int makeKey(Ip::Address
&src_addr
) const;
252 unsigned char makeHostKey(Ip::Address
&src_addr
) const;
255 VectorMap
<unsigned char, ClassCBucket
> buckets
;
259 friend class ClassCHostPool::Id
;
261 /// \ingroup DelayPoolsInternal
262 class Id
:public DelayIdComposite
266 void *operator new(size_t);
267 void operator delete (void *);
268 Id (RefCount
<ClassCHostPool
>, unsigned char, unsigned char);
269 virtual int bytesWanted (int min
, int max
) const;
270 virtual void bytesIn(int qty
);
273 RefCount
<ClassCHostPool
> theClassCHost
;
274 unsigned char theNet
;
275 unsigned char theHost
;
280 Aggregate::AggregateId::delayRead(DeferredRead
const &aRead
)
282 theAggregate
->delayRead(aRead
);
286 CommonPool::operator new(size_t size
)
288 DelayPools::MemoryUsed
+= sizeof (CommonPool
);
289 return ::operator new (size
);
293 CommonPool::operator delete(void *address
)
295 DelayPools::MemoryUsed
-= sizeof(CommonPool
);
296 ::operator delete(address
);
300 CommonPool::Factory(unsigned char _class
, CompositePoolNode::Pointer
& compositeCopy
)
302 CommonPool
*result
= new CommonPool
;
310 compositeCopy
= new Aggregate
;
311 result
->typeLabel
= "1";
315 result
->typeLabel
= "2";
317 DelayVector::Pointer temp
= new DelayVector
;
318 compositeCopy
= temp
.getRaw();
319 temp
->push_back (new Aggregate
);
320 temp
->push_back(new IndividualPool
);
325 result
->typeLabel
= "3";
327 DelayVector::Pointer temp
= new DelayVector
;
328 compositeCopy
= temp
.getRaw();
329 temp
->push_back (new Aggregate
);
330 temp
->push_back (new ClassCNetPool
);
331 temp
->push_back (new ClassCHostPool
);
336 result
->typeLabel
= "4";
338 DelayVector::Pointer temp
= new DelayVector
;
339 compositeCopy
= temp
.getRaw();
340 temp
->push_back (new Aggregate
);
341 temp
->push_back (new ClassCNetPool
);
342 temp
->push_back (new ClassCHostPool
);
344 temp
->push_back (new DelayUser
);
350 result
->typeLabel
= "5";
351 compositeCopy
= new DelayTagged
;
355 fatal ("unknown delay pool class");
362 CommonPool::CommonPool()
366 ClassCBucket::update (DelaySpec
const &rate
, int incr
)
368 /* If we aren't active, don't try to update us ! */
369 assert (rate
.restore_bps
!= -1);
371 for (unsigned int j
= 0; j
< individuals
.size(); ++j
)
372 individuals
.values
[j
].update (rate
, incr
);
376 ClassCBucket::stats(StoreEntry
*sentry
)const
378 for (unsigned int j
= 0; j
< individuals
.size(); ++j
) {
379 assert (individualUsed (j
));
380 storeAppendPrintf(sentry
, " %d:",individuals
.key_map
[j
]);
381 individuals
.values
[j
].stats (sentry
);
386 ClassCBucket::findHostMapPosition (unsigned char const host
) const
388 return individuals
.findKeyIndex(host
);
392 ClassCBucket::individualUsed (unsigned int index
)const
394 return individuals
.indexUsed(index
);
398 ClassCBucket::individualAllocated (unsigned char host
) const
400 return individualUsed(findHostMapPosition (host
));
404 ClassCBucket::hostPosition (DelaySpec
&rate
, unsigned char const host
)
406 if (individualAllocated (host
))
407 return findHostMapPosition(host
);
409 assert (!individualUsed (findHostMapPosition(host
)));
411 unsigned char result
= findHostMapPosition(host
);
413 initHostIndex (rate
, result
, host
);
419 ClassCBucket::initHostIndex (DelaySpec
&rate
, unsigned char index
, unsigned char host
)
421 assert (!individualUsed(index
));
423 unsigned char const newIndex
= individuals
.insert (host
);
425 /* give the bucket a default value */
426 individuals
.values
[newIndex
].init (rate
);
430 CompositePoolNode::operator new(size_t size
)
432 DelayPools::MemoryUsed
+= sizeof (CompositePoolNode
);
433 return ::operator new (size
);
437 CompositePoolNode::operator delete (void *address
)
439 DelayPools::MemoryUsed
-= sizeof (CompositePoolNode
);
440 ::operator delete (address
);
444 Aggregate::operator new(size_t size
)
446 DelayPools::MemoryUsed
+= sizeof (Aggregate
);
447 return ::operator new (size
);
451 Aggregate::operator delete (void *address
)
453 DelayPools::MemoryUsed
-= sizeof (Aggregate
);
454 ::operator delete (address
);
457 Aggregate::Aggregate()
459 theBucket
.init (*rate());
460 DelayPools::registerForUpdates (this);
463 Aggregate::~Aggregate()
465 DelayPools::deregisterForUpdates (this);
469 Aggregate::stats(StoreEntry
* sentry
)
471 rate()->stats (sentry
, "Aggregate");
473 if (rate()->restore_bps
== -1)
476 storeAppendPrintf(sentry
, "\t\tCurrent: ");
478 theBucket
.stats(sentry
);
480 storeAppendPrintf(sentry
, "\n\n");
484 Aggregate::dump(StoreEntry
*entry
) const
486 rate()->dump (entry
);
490 Aggregate::update(int incr
)
492 theBucket
.update(*rate(), incr
);
502 DelayIdComposite::Pointer
503 Aggregate::id(CompositeSelectionDetails
&details
)
505 if (rate()->restore_bps
!= -1)
506 return new AggregateId (this);
508 return new NullDelayId
;
512 Aggregate::AggregateId::operator new(size_t size
)
514 DelayPools::MemoryUsed
+= sizeof (AggregateId
);
515 return ::operator new (size
);
519 Aggregate::AggregateId::operator delete (void *address
)
521 DelayPools::MemoryUsed
-= sizeof (AggregateId
);
522 ::operator delete (address
);
525 Aggregate::AggregateId::AggregateId(RefCount
<Aggregate
> anAggregate
) : theAggregate(anAggregate
)
529 Aggregate::AggregateId::bytesWanted (int min
, int max
) const
531 return theAggregate
->theBucket
.bytesWanted(min
, max
);
535 Aggregate::AggregateId::bytesIn(int qty
)
537 theAggregate
->theBucket
.bytesIn(qty
);
538 theAggregate
->kickReads();
541 DelayPool
*DelayPools::delay_data
= NULL
;
542 time_t DelayPools::LastUpdate
= 0;
543 unsigned short DelayPools::pools_ (0);
546 DelayPools::RegisterWithCacheManager(void)
548 Mgr::RegisterAction("delay", "Delay Pool Levels", Stats
, 0, 1);
554 LastUpdate
= getCurrentTime();
555 RegisterWithCacheManager();
559 DelayPools::InitDelayData()
564 DelayPools::delay_data
= new DelayPool
[pools()];
566 DelayPools::MemoryUsed
+= pools() * sizeof(DelayPool
);
568 eventAdd("DelayPools::Update", DelayPools::Update
, NULL
, 1.0, 1);
572 DelayPools::FreeDelayData()
574 eventDelete(DelayPools::Update
, NULL
);
575 delete[] DelayPools::delay_data
;
576 DelayPools::MemoryUsed
-= pools() * sizeof(*DelayPools::delay_data
);
581 DelayPools::Update(void *unused
)
586 eventAdd("DelayPools::Update", Update
, NULL
, 1.0, 1);
588 int incr
= squid_curtime
- LastUpdate
;
593 LastUpdate
= squid_curtime
;
595 Vector
<Updateable
*>::iterator pos
= toUpdate
.begin();
597 while (pos
!= toUpdate
.end()) {
598 (*pos
)->update(incr
);
604 DelayPools::registerForUpdates(Updateable
*anObject
)
606 /* Assume no doubles */
607 toUpdate
.push_back(anObject
);
611 DelayPools::deregisterForUpdates (Updateable
*anObject
)
613 Vector
<Updateable
*>::iterator pos
= toUpdate
.begin();
615 while (pos
!= toUpdate
.end() && *pos
!= anObject
) {
619 if (pos
!= toUpdate
.end()) {
620 /* move all objects down one */
621 Vector
<Updateable
*>::iterator temp
= pos
;
624 while (pos
!= toUpdate
.end()) {
634 Vector
<Updateable
*> DelayPools::toUpdate
;
637 DelayPools::Stats(StoreEntry
* sentry
)
641 storeAppendPrintf(sentry
, "Delay pools configured: %d\n\n", DelayPools::pools());
643 for (i
= 0; i
< DelayPools::pools(); ++i
) {
644 if (DelayPools::delay_data
[i
].theComposite().getRaw()) {
645 storeAppendPrintf(sentry
, "Pool: %d\n\tClass: %s\n\n", i
+ 1, DelayPools::delay_data
[i
].pool
->theClassTypeLabel());
646 DelayPools::delay_data
[i
].theComposite()->stats (sentry
);
648 storeAppendPrintf(sentry
, "\tMisconfigured pool.\n\n");
651 storeAppendPrintf(sentry
, "Memory Used: %d bytes\n", (int) DelayPools::MemoryUsed
);
655 DelayPools::FreePools()
657 if (!DelayPools::pools())
670 DelayPools::pools(unsigned short newPools
)
673 debugs(3, DBG_CRITICAL
, "parse_delay_pool_count: multiple delay_pools lines, aborting all previous delay_pools config");
683 template <class Key
, class Value
>
684 VectorMap
<Key
,Value
>::VectorMap() : nextMapPosition(0)
687 template <class Key
, class Value
>
689 VectorMap
<Key
,Value
>::size() const
691 return nextMapPosition
;
694 template <class Key
, class Value
>
696 VectorMap
<Key
,Value
>::insert (Key
const key
)
698 unsigned char index
= findKeyIndex (key
);
699 assert (!indexUsed(index
));
701 key_map
[index
] = key
;
709 IndividualPool::operator new(size_t size
)
711 DelayPools::MemoryUsed
+= sizeof (IndividualPool
);
712 return ::operator new (size
);
716 IndividualPool::operator delete (void *address
)
718 DelayPools::MemoryUsed
-= sizeof (IndividualPool
);
719 ::operator delete (address
);
722 VectorPool::VectorPool()
724 DelayPools::registerForUpdates (this);
727 VectorPool::~VectorPool()
729 DelayPools::deregisterForUpdates (this);
733 VectorPool::stats(StoreEntry
* sentry
)
735 rate()->stats (sentry
, label());
737 if (rate()->restore_bps
== -1) {
738 storeAppendPrintf(sentry
, "\n\n");
742 storeAppendPrintf(sentry
, "\t\tCurrent:");
744 for (unsigned int i
= 0; i
< buckets
.size(); ++i
) {
745 storeAppendPrintf(sentry
, " %d:", buckets
.key_map
[i
]);
746 buckets
.values
[i
].stats(sentry
);
750 storeAppendPrintf(sentry
, " Not used yet.");
752 storeAppendPrintf(sentry
, "\n\n");
756 VectorPool::dump(StoreEntry
*entry
) const
758 rate()->dump (entry
);
762 VectorPool::update(int incr
)
764 if (rate()->restore_bps
== -1)
767 for (unsigned int i
= 0; i
< buckets
.size(); ++i
)
768 buckets
.values
[i
].update (*rate(), incr
);
778 VectorPool::keyAllocated (unsigned char const key
) const
780 return buckets
.indexUsed(buckets
.findKeyIndex (key
));
783 template <class Key
, class Value
>
785 VectorMap
<Key
,Value
>::indexUsed (unsigned char const index
) const
787 return index
< size();
790 /** returns the used position, or the position to allocate */
791 template <class Key
, class Value
>
793 VectorMap
<Key
,Value
>::findKeyIndex (Key
const key
) const
795 for (unsigned int index
= 0; index
< size(); ++index
) {
796 assert(indexUsed(index
));
798 if (key_map
[index
] == key
)
806 DelayIdComposite::Pointer
807 VectorPool::id(CompositeSelectionDetails
&details
)
809 if (rate()->restore_bps
== -1)
810 return new NullDelayId
;
812 /* non-IPv4 are not able to provide IPv4-bitmask for this pool type key. */
813 if ( !details
.src_addr
.isIPv4() )
814 return new NullDelayId
;
816 unsigned int key
= makeKey(details
.src_addr
);
818 if (keyAllocated(key
))
819 return new Id(this, buckets
.findKeyIndex(key
));
821 unsigned char const resultIndex
= buckets
.insert(key
);
823 buckets
.values
[resultIndex
].init(*rate());
825 return new Id(this, resultIndex
);
829 VectorPool::Id::operator new(size_t size
)
831 DelayPools::MemoryUsed
+= sizeof (Id
);
832 return ::operator new (size
);
836 VectorPool::Id::operator delete(void *address
)
838 DelayPools::MemoryUsed
-= sizeof (Id
);
839 ::operator delete (address
);
842 VectorPool::Id::Id(VectorPool::Pointer aPool
, int anIndex
) : theVector (aPool
), theIndex (anIndex
)
846 VectorPool::Id::bytesWanted (int min
, int max
) const
848 return theVector
->buckets
.values
[theIndex
].bytesWanted (min
, max
);
852 VectorPool::Id::bytesIn(int qty
)
854 theVector
->buckets
.values
[theIndex
].bytesIn (qty
);
858 IndividualPool::makeKey(Ip::Address
&src_addr
) const
860 /* IPv4 required for this pool */
861 if ( !src_addr
.isIPv4() )
865 src_addr
.getInAddr(host
);
866 return (ntohl(host
.s_addr
) & 0xff);
870 ClassCNetPool::operator new(size_t size
)
872 DelayPools::MemoryUsed
+= sizeof (ClassCNetPool
);
873 return ::operator new (size
);
877 ClassCNetPool::operator delete (void *address
)
879 DelayPools::MemoryUsed
-= sizeof (ClassCNetPool
);
880 ::operator delete (address
);
884 ClassCNetPool::makeKey(Ip::Address
&src_addr
) const
886 /* IPv4 required for this pool */
887 if ( !src_addr
.isIPv4() )
891 src_addr
.getInAddr(net
);
892 return ( (ntohl(net
.s_addr
) >> 8) & 0xff);
895 ClassCHostPool::ClassCHostPool()
897 DelayPools::registerForUpdates (this);
900 ClassCHostPool::~ClassCHostPool()
902 DelayPools::deregisterForUpdates (this);
906 ClassCHostPool::stats(StoreEntry
* sentry
)
908 rate()->stats (sentry
, label());
910 if (rate()->restore_bps
== -1) {
911 storeAppendPrintf(sentry
, "\n\n");
915 for (unsigned int index
= 0; index
< buckets
.size(); ++index
) {
916 storeAppendPrintf(sentry
, "\t\tCurrent [Network %d]:", buckets
.key_map
[index
]);
917 buckets
.values
[index
].stats (sentry
);
918 storeAppendPrintf(sentry
, "\n");
922 storeAppendPrintf(sentry
, "\t\tCurrent [All networks]: Not used yet.\n");
924 storeAppendPrintf(sentry
, "\n\n");
928 ClassCHostPool::dump(StoreEntry
*entry
) const
930 rate()->dump (entry
);
934 ClassCHostPool::update(int incr
)
936 if (rate()->restore_bps
== -1)
939 for (unsigned int i
= 0; i
< buckets
.size(); ++i
)
940 buckets
.values
[i
].update (*rate(), incr
);
944 ClassCHostPool::parse()
950 ClassCHostPool::keyAllocated (unsigned char const key
) const
952 return buckets
.indexUsed(buckets
.findKeyIndex (key
));
956 ClassCHostPool::makeHostKey(Ip::Address
&src_addr
) const
958 /* IPv4 required for this pool */
959 if ( !src_addr
.isIPv4() )
962 /* Temporary bypass for IPv4-only */
964 src_addr
.getInAddr(host
);
965 return (ntohl(host
.s_addr
) & 0xff);
969 ClassCHostPool::makeKey(Ip::Address
&src_addr
) const
971 /* IPv4 required for this pool */
972 if ( !src_addr
.isIPv4() )
976 src_addr
.getInAddr(net
);
977 return ( (ntohl(net
.s_addr
) >> 8) & 0xff);
980 DelayIdComposite::Pointer
981 ClassCHostPool::id(CompositeSelectionDetails
&details
)
983 if (rate()->restore_bps
== -1)
984 return new NullDelayId
;
986 /* non-IPv4 are not able to provide IPv4-bitmask for this pool type key. */
987 if ( !details
.src_addr
.isIPv4() )
988 return new NullDelayId
;
990 unsigned int key
= makeKey (details
.src_addr
);
992 unsigned char host
= makeHostKey (details
.src_addr
);
994 unsigned char hostIndex
;
996 unsigned char netIndex
;
998 if (keyAllocated (key
))
999 netIndex
= buckets
.findKeyIndex(key
);
1001 netIndex
= buckets
.insert (key
);
1003 hostIndex
= buckets
.values
[netIndex
].hostPosition (*rate(), host
);
1005 return new Id (this, netIndex
, hostIndex
);
1009 ClassCHostPool::Id::operator new(size_t size
)
1011 DelayPools::MemoryUsed
+= sizeof (Id
);
1012 return ::operator new (size
);
1016 ClassCHostPool::Id::operator delete (void *address
)
1018 DelayPools::MemoryUsed
-= sizeof (Id
);
1019 ::operator delete (address
);
1022 ClassCHostPool::Id::Id (ClassCHostPool::Pointer aPool
, unsigned char aNet
, unsigned char aHost
) : theClassCHost (aPool
), theNet (aNet
), theHost (aHost
)
1026 ClassCHostPool::Id::bytesWanted (int min
, int max
) const
1028 return theClassCHost
->buckets
.values
[theNet
].individuals
.values
[theHost
].bytesWanted (min
, max
);
1032 ClassCHostPool::Id::bytesIn(int qty
)
1034 theClassCHost
->buckets
.values
[theNet
].individuals
.values
[theHost
].bytesIn (qty
);
1037 #endif /* USE_DELAY_POOLS */