2 * $Id: delay_pools.cc,v 1.51 2008/02/26 21:49:34 amosjeffries Exp $
4 * DEBUG: section 77 Delay Pools
5 * AUTHOR: Robert Collins <robertc@squid-cache.org>
6 * Based upon original delay pools code by
7 * David Luyer <david@luyer.net>
9 * SQUID Web Proxy Cache http://www.squid-cache.org/
10 * ----------------------------------------------------------
12 * Squid is the result of efforts by numerous individuals from
13 * the Internet community; see the CONTRIBUTORS file for full
14 * details. Many organizations have provided support for Squid's
15 * development; see the SPONSORS file for full details. Squid is
16 * Copyrighted (C) 2001 by the Regents of the University of
17 * California; see the COPYRIGHT file for full details. Squid
18 * incorporates software developed and/or copyrighted by other
19 * sources; see the CREDITS file for full details.
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
36 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
40 \defgroup DelayPoolsInternal Delay Pools Internal
41 \ingroup DelayPoolsAPI
48 #include "CacheManager.h"
49 #include "DelaySpec.h"
50 #include "DelayPools.h"
52 #include "StoreClient.h"
54 #include "MemObject.h"
55 #include "client_side_request.h"
56 #include "ConfigParser.h"
59 #include "SquidString.h"
60 #include "SquidTime.h"
61 #include "CommonPool.h"
62 #include "CompositePoolNode.h"
63 #include "DelayPool.h"
64 #include "DelayVector.h"
65 #include "NullDelayId.h"
66 #include "DelayBucket.h"
67 #include "DelayUser.h"
68 #include "DelayTagged.h"
69 #include "IPAddress.h"
71 /// \ingroup DelayPoolsInternal
72 long DelayPools::MemoryUsed
= 0;
74 /// \ingroup DelayPoolsInternal
75 class Aggregate
: public CompositePoolNode
79 typedef RefCount
<Aggregate
> Pointer
;
80 void *operator new(size_t);
81 void operator delete (void *);
84 virtual DelaySpec
*rate() {return &spec
;}
86 virtual DelaySpec
const *rate() const {return &spec
;}
88 virtual void stats(StoreEntry
* sentry
);
89 virtual void dump(StoreEntry
*entry
) const;
90 virtual void update(int incr
);
93 virtual DelayIdComposite::Pointer
id(CompositeSelectionDetails
&);
97 /// \ingroup DelayPoolsInternal
98 class AggregateId
:public DelayIdComposite
102 void *operator new(size_t);
103 void operator delete (void *);
104 AggregateId (RefCount
<Aggregate
>);
105 virtual int bytesWanted (int min
, int max
) const;
106 virtual void bytesIn(int qty
);
107 virtual void delayRead(DeferredRead
const &);
110 RefCount
<Aggregate
> theAggregate
;
113 friend class AggregateId
;
115 DelayBucket theBucket
;
119 /// \ingroup DelayPoolsInternal
120 template <class Key
, class Value
>
126 unsigned int size() const;
127 unsigned char findKeyIndex (Key
const key
) const;
128 bool indexUsed (unsigned char const index
) const;
129 unsigned int insert (Key
const key
);
131 #define IND_MAP_SZ 256
133 Key key_map
[IND_MAP_SZ
];
134 Value values
[IND_MAP_SZ
];
137 unsigned int nextMapPosition
;
140 /// \ingroup DelayPoolsInternal
141 class VectorPool
: public CompositePoolNode
145 typedef RefCount
<VectorPool
> Pointer
;
146 virtual void dump(StoreEntry
*entry
) const;
147 virtual void parse();
148 virtual void update(int incr
);
149 virtual void stats(StoreEntry
* sentry
);
151 virtual DelayIdComposite::Pointer
id(CompositeSelectionDetails
&);
152 VectorMap
<unsigned char, DelayBucket
> buckets
;
157 bool keyAllocated (unsigned char const key
) const;
158 virtual DelaySpec
*rate() {return &spec
;}
160 virtual DelaySpec
const *rate() const {return &spec
;}
162 virtual char const *label() const = 0;
164 virtual unsigned int makeKey (IPAddress
&src_addr
) const = 0;
168 /// \ingroup DelayPoolsInternal
169 class Id
:public DelayIdComposite
173 void *operator new(size_t);
174 void operator delete (void *);
175 Id (RefCount
<VectorPool
>, int);
176 virtual int bytesWanted (int min
, int max
) const;
177 virtual void bytesIn(int qty
);
180 RefCount
<VectorPool
> theVector
;
185 /// \ingroup DelayPoolsInternal
186 class IndividualPool
: public VectorPool
190 void *operator new(size_t);
191 void operator delete (void *);
194 virtual char const *label() const {return "Individual";}
196 virtual unsigned int makeKey (IPAddress
&src_addr
) const;
200 /// \ingroup DelayPoolsInternal
201 class ClassCNetPool
: public VectorPool
205 void *operator new(size_t);
206 void operator delete (void *);
209 virtual char const *label() const {return "Network";}
211 virtual unsigned int makeKey (IPAddress
&src_addr
) const;
214 /* don't use remote storage for these */
215 /// \ingroup DelayPoolsInternal
220 bool individualUsed (unsigned int index
)const;
221 unsigned char findHostMapPosition (unsigned char const host
) const;
222 bool individualAllocated (unsigned char host
) const;
223 unsigned char hostPosition (DelaySpec
&rate
, unsigned char const host
);
224 void initHostIndex (DelaySpec
&rate
, unsigned char index
, unsigned char host
);
225 void update (DelaySpec
const &, int incr
);
226 void stats(StoreEntry
*)const;
229 VectorMap
<unsigned char, DelayBucket
> individuals
;
232 /// \ingroup DelayPoolsInternal
233 class ClassCHostPool
: public CompositePoolNode
237 typedef RefCount
<ClassCHostPool
> Pointer
;
238 virtual void dump(StoreEntry
*entry
) const;
239 virtual void parse();
240 virtual void update(int incr
);
241 virtual void stats(StoreEntry
* sentry
);
243 virtual DelayIdComposite::Pointer
id(CompositeSelectionDetails
&);
248 bool keyAllocated (unsigned char const key
) const;
249 virtual DelaySpec
*rate() {return &spec
;}
251 virtual DelaySpec
const *rate() const {return &spec
;}
253 virtual char const *label() const {return "Individual";}
255 virtual unsigned int makeKey (IPAddress
&src_addr
) const;
257 unsigned char makeHostKey (IPAddress
&src_addr
) const;
260 VectorMap
<unsigned char, ClassCBucket
> buckets
;
264 friend class ClassCHostPool::Id
;
266 /// \ingroup DelayPoolsInternal
267 class Id
:public DelayIdComposite
271 void *operator new(size_t);
272 void operator delete (void *);
273 Id (RefCount
<ClassCHostPool
>, unsigned char, unsigned char);
274 virtual int bytesWanted (int min
, int max
) const;
275 virtual void bytesIn(int qty
);
278 RefCount
<ClassCHostPool
> theClassCHost
;
279 unsigned char theNet
;
280 unsigned char theHost
;
285 Aggregate::AggregateId::delayRead(DeferredRead
const &aRead
)
287 theAggregate
->delayRead(aRead
);
291 CommonPool::operator new(size_t size
)
293 DelayPools::MemoryUsed
+= sizeof (CommonPool
);
294 return ::operator new (size
);
298 CommonPool::operator delete (void *address
)
300 DelayPools::MemoryUsed
-= sizeof (CommonPool
);
301 ::operator delete (address
);
305 CommonPool::Factory(unsigned char _class
, CompositePoolNode::Pointer
& compositeCopy
)
307 CommonPool
*result
= new CommonPool
;
315 compositeCopy
= new Aggregate
;
316 result
->typeLabel
= "1";
320 result
->typeLabel
= "2";
322 DelayVector::Pointer temp
= new DelayVector
;
323 compositeCopy
= temp
.getRaw();
324 temp
->push_back (new Aggregate
);
325 temp
->push_back(new IndividualPool
);
331 result
->typeLabel
= "3";
333 DelayVector::Pointer temp
= new DelayVector
;
334 compositeCopy
= temp
.getRaw();
335 temp
->push_back (new Aggregate
);
336 temp
->push_back (new ClassCNetPool
);
337 temp
->push_back (new ClassCHostPool
);
343 result
->typeLabel
= "4";
345 DelayVector::Pointer temp
= new DelayVector
;
346 compositeCopy
= temp
.getRaw();
347 temp
->push_back (new Aggregate
);
348 temp
->push_back (new ClassCNetPool
);
349 temp
->push_back (new ClassCHostPool
);
350 temp
->push_back (new DelayUser
);
356 result
->typeLabel
= "5";
357 compositeCopy
= new DelayTagged
;
361 fatal ("unknown delay pool class");
368 CommonPool::CommonPool()
372 ClassCBucket::update (DelaySpec
const &rate
, int incr
)
374 /* If we aren't active, don't try to update us ! */
375 assert (rate
.restore_bps
!= -1);
377 for (unsigned char j
= 0; j
< individuals
.size(); ++j
)
378 individuals
.values
[j
].update (rate
, incr
);
382 ClassCBucket::stats(StoreEntry
*sentry
)const
384 for (unsigned int j
= 0; j
< individuals
.size(); ++j
) {
385 assert (individualUsed (j
));
386 storeAppendPrintf(sentry
, " %d:",individuals
.key_map
[j
]);
387 individuals
.values
[j
].stats (sentry
);
392 ClassCBucket::findHostMapPosition (unsigned char const host
) const
394 return individuals
.findKeyIndex(host
);
398 ClassCBucket::individualUsed (unsigned int index
)const
400 return individuals
.indexUsed(index
);
404 ClassCBucket::individualAllocated (unsigned char host
) const
406 return individualUsed(findHostMapPosition (host
));
410 ClassCBucket::hostPosition (DelaySpec
&rate
, unsigned char const host
)
412 if (individualAllocated (host
))
413 return findHostMapPosition(host
);
415 assert (!individualUsed (findHostMapPosition(host
)));
417 unsigned char result
= findHostMapPosition(host
);
419 initHostIndex (rate
, result
, host
);
425 ClassCBucket::initHostIndex (DelaySpec
&rate
, unsigned char index
, unsigned char host
)
427 assert (!individualUsed(index
));
429 unsigned char const newIndex
= individuals
.insert (host
);
431 /* give the bucket a default value */
432 individuals
.values
[newIndex
].init (rate
);
436 CompositePoolNode::operator new(size_t size
)
438 DelayPools::MemoryUsed
+= sizeof (CompositePoolNode
);
439 return ::operator new (size
);
443 CompositePoolNode::operator delete (void *address
)
445 DelayPools::MemoryUsed
-= sizeof (CompositePoolNode
);
446 ::operator delete (address
);
450 Aggregate::operator new(size_t size
)
452 DelayPools::MemoryUsed
+= sizeof (Aggregate
);
453 return ::operator new (size
);
457 Aggregate::operator delete (void *address
)
459 DelayPools::MemoryUsed
-= sizeof (Aggregate
);
460 ::operator delete (address
);
463 Aggregate::Aggregate()
465 theBucket
.init (*rate());
466 DelayPools::registerForUpdates (this);
469 Aggregate::~Aggregate()
471 DelayPools::deregisterForUpdates (this);
475 Aggregate::stats(StoreEntry
* sentry
)
477 rate()->stats (sentry
, "Aggregate");
479 if (rate()->restore_bps
== -1)
482 storeAppendPrintf(sentry
, "\t\tCurrent: ");
484 theBucket
.stats(sentry
);
486 storeAppendPrintf(sentry
, "\n\n");
490 Aggregate::dump(StoreEntry
*entry
) const
492 rate()->dump (entry
);
496 Aggregate::update(int incr
)
498 theBucket
.update(*rate(), incr
);
508 DelayIdComposite::Pointer
510 Aggregate::id(CompositeSelectionDetails
&details
)
512 if (rate()->restore_bps
!= -1)
513 return new AggregateId (this);
515 return new NullDelayId
;
519 Aggregate::AggregateId::operator new(size_t size
)
521 DelayPools::MemoryUsed
+= sizeof (AggregateId
);
522 return ::operator new (size
);
526 Aggregate::AggregateId::operator delete (void *address
)
528 DelayPools::MemoryUsed
-= sizeof (AggregateId
);
529 ::operator delete (address
);
532 Aggregate::AggregateId::AggregateId(RefCount
<Aggregate
> anAggregate
) : theAggregate(anAggregate
)
536 Aggregate::AggregateId::bytesWanted (int min
, int max
) const
538 return theAggregate
->theBucket
.bytesWanted(min
, max
);
542 Aggregate::AggregateId::bytesIn(int qty
)
544 theAggregate
->theBucket
.bytesIn(qty
);
545 theAggregate
->kickReads();
548 DelayPool
*DelayPools::delay_data
= NULL
;
549 time_t DelayPools::LastUpdate
= 0;
550 unsigned short DelayPools::pools_ (0);
555 LastUpdate
= getCurrentTime();
556 RegisterWithCacheManager();
560 DelayPools::RegisterWithCacheManager(void)
562 CacheManager::GetInstance()->
563 registerAction("delay", "Delay Pool Levels", Stats
, 0, 1);
567 DelayPools::InitDelayData()
572 DelayPools::delay_data
= new DelayPool
[pools()];
574 DelayPools::MemoryUsed
+= pools() * sizeof(DelayPool
);
576 eventAdd("DelayPools::Update", DelayPools::Update
, NULL
, 1.0, 1);
580 DelayPools::FreeDelayData()
582 eventDelete(DelayPools::Update
, NULL
);
583 delete[] DelayPools::delay_data
;
584 DelayPools::MemoryUsed
-= pools() * sizeof(*DelayPools::delay_data
);
589 DelayPools::Update(void *unused
)
594 eventAdd("DelayPools::Update", Update
, NULL
, 1.0, 1);
596 int incr
= squid_curtime
- LastUpdate
;
601 LastUpdate
= squid_curtime
;
603 Vector
<Updateable
*>::iterator pos
= toUpdate
.begin();
605 while (pos
!= toUpdate
.end()) {
606 (*pos
)->update(incr
);
612 DelayPools::registerForUpdates(Updateable
*anObject
)
614 /* Assume no doubles */
615 toUpdate
.push_back(anObject
);
619 DelayPools::deregisterForUpdates (Updateable
*anObject
)
621 Vector
<Updateable
*>::iterator pos
= toUpdate
.begin();
623 while (pos
!= toUpdate
.end() && *pos
!= anObject
) {
627 if (pos
!= toUpdate
.end()) {
628 /* move all objects down one */
629 Vector
<Updateable
*>::iterator temp
= pos
;
632 while (pos
!= toUpdate
.end()) {
642 Vector
<Updateable
*> DelayPools::toUpdate
;
645 DelayPools::Stats(StoreEntry
* sentry
)
649 storeAppendPrintf(sentry
, "Delay pools configured: %d\n\n", DelayPools::pools());
651 for (i
= 0; i
< DelayPools::pools(); ++i
) {
652 if (DelayPools::delay_data
[i
].theComposite().getRaw()) {
653 storeAppendPrintf(sentry
, "Pool: %d\n\tClass: %s\n\n", i
+ 1, DelayPools::delay_data
[i
].pool
->theClassTypeLabel());
654 DelayPools::delay_data
[i
].theComposite()->stats (sentry
);
656 storeAppendPrintf(sentry
, "\tMisconfigured pool.\n\n");
659 storeAppendPrintf(sentry
, "Memory Used: %d bytes\n", (int) DelayPools::MemoryUsed
);
663 DelayPools::FreePools()
665 if (!DelayPools::pools())
678 DelayPools::pools (u_short newPools
)
681 debugs(3, 0, "parse_delay_pool_count: multiple delay_pools lines, aborting all previous delay_pools config");
691 template <class Key
, class Value
>
692 VectorMap
<Key
,Value
>::VectorMap() : nextMapPosition(0)
695 template <class Key
, class Value
>
697 VectorMap
<Key
,Value
>::size() const
699 return nextMapPosition
;
702 template <class Key
, class Value
>
704 VectorMap
<Key
,Value
>::insert (Key
const key
)
706 unsigned char index
= findKeyIndex (key
);
707 assert (!indexUsed(index
));
709 key_map
[index
] = key
;
717 IndividualPool::operator new(size_t size
)
719 DelayPools::MemoryUsed
+= sizeof (IndividualPool
);
720 return ::operator new (size
);
724 IndividualPool::operator delete (void *address
)
726 DelayPools::MemoryUsed
-= sizeof (IndividualPool
);
727 ::operator delete (address
);
730 VectorPool::VectorPool()
732 DelayPools::registerForUpdates (this);
735 VectorPool::~VectorPool()
737 DelayPools::deregisterForUpdates (this);
741 VectorPool::stats(StoreEntry
* sentry
)
743 rate()->stats (sentry
, label());
745 if (rate()->restore_bps
== -1) {
746 storeAppendPrintf(sentry
, "\n\n");
750 storeAppendPrintf(sentry
, "\t\tCurrent:");
752 for (unsigned int i
= 0; i
< buckets
.size(); i
++) {
753 storeAppendPrintf(sentry
, " %d:", buckets
.key_map
[i
]);
754 buckets
.values
[i
].stats(sentry
);
758 storeAppendPrintf(sentry
, " Not used yet.");
760 storeAppendPrintf(sentry
, "\n\n");
764 VectorPool::dump(StoreEntry
*entry
) const
766 rate()->dump (entry
);
770 VectorPool::update(int incr
)
772 if (rate()->restore_bps
== -1)
775 for (unsigned int i
= 0; i
< buckets
.size(); ++i
)
776 buckets
.values
[i
].update (*rate(), incr
);
786 VectorPool::keyAllocated (unsigned char const key
) const
788 return buckets
.indexUsed(buckets
.findKeyIndex (key
));
791 template <class Key
, class Value
>
793 VectorMap
<Key
,Value
>::indexUsed (unsigned char const index
) const
795 return index
< size();
798 /** returns the used position, or the position to allocate */
799 template <class Key
, class Value
>
801 VectorMap
<Key
,Value
>::findKeyIndex (Key
const key
) const
803 for (unsigned int index
= 0; index
< size(); ++index
) {
804 assert (indexUsed (index
));
806 if (key_map
[index
] == key
)
814 DelayIdComposite::Pointer
816 VectorPool::id(CompositeSelectionDetails
&details
)
818 if (rate()->restore_bps
== -1)
819 return new NullDelayId
;
821 unsigned int key
= makeKey (details
.src_addr
);
823 if (keyAllocated (key
))
824 return new Id (this, buckets
.findKeyIndex(key
));
826 unsigned char const resultIndex
= buckets
.insert(key
);
828 buckets
.values
[resultIndex
].init (*rate());
830 return new Id(this, resultIndex
);
834 VectorPool::Id::operator new(size_t size
)
836 DelayPools::MemoryUsed
+= sizeof (Id
);
837 return ::operator new (size
);
841 VectorPool::Id::operator delete (void *address
)
843 DelayPools::MemoryUsed
-= sizeof (Id
);
844 ::operator delete (address
);
847 VectorPool::Id::Id (VectorPool::Pointer aPool
, int anIndex
) : theVector (aPool
), theIndex (anIndex
)
851 VectorPool::Id::bytesWanted (int min
, int max
) const
853 return theVector
->buckets
.values
[theIndex
].bytesWanted (min
, max
);
857 VectorPool::Id::bytesIn(int qty
)
859 theVector
->buckets
.values
[theIndex
].bytesIn (qty
);
863 IndividualPool::makeKey (IPAddress
&src_addr
) const
865 /* FIXME INET6 : IPv6 requires a 64-128 bit result from this function */
866 if( !src_addr
.IsIPv4() )
869 /* Temporary bypass for IPv4-only */
871 src_addr
.GetInAddr(host
);
872 return (ntohl(host
.s_addr
) & 0xff);
876 ClassCNetPool::operator new(size_t size
)
878 DelayPools::MemoryUsed
+= sizeof (ClassCNetPool
);
879 return ::operator new (size
);
883 ClassCNetPool::operator delete (void *address
)
885 DelayPools::MemoryUsed
-= sizeof (ClassCNetPool
);
886 ::operator delete (address
);
890 ClassCNetPool::makeKey (IPAddress
&src_addr
) const
892 /* FIXME INET6 : IPv6 requires a 64-128 bit result from this function */
893 if( !src_addr
.IsIPv4() )
896 /* Temporary bypass for IPv4-only */
898 src_addr
.GetInAddr(net
);
899 return ( (ntohl(net
.s_addr
) >> 8) & 0xff);
903 ClassCHostPool::ClassCHostPool()
905 DelayPools::registerForUpdates (this);
908 ClassCHostPool::~ClassCHostPool()
910 DelayPools::deregisterForUpdates (this);
914 ClassCHostPool::stats(StoreEntry
* sentry
)
916 rate()->stats (sentry
, label());
918 if (rate()->restore_bps
== -1) {
919 storeAppendPrintf(sentry
, "\n\n");
923 for (unsigned int index
= 0; index
< buckets
.size(); ++index
) {
924 storeAppendPrintf(sentry
, "\t\tCurrent [Network %d]:", buckets
.key_map
[index
]);
925 buckets
.values
[index
].stats (sentry
);
926 storeAppendPrintf(sentry
, "\n");
930 storeAppendPrintf(sentry
, "\t\tCurrent [All networks]: Not used yet.\n");
932 storeAppendPrintf(sentry
, "\n\n");
936 ClassCHostPool::dump(StoreEntry
*entry
) const
938 rate()->dump (entry
);
942 ClassCHostPool::update(int incr
)
944 if (rate()->restore_bps
== -1)
947 for (unsigned int i
= 0; i
< buckets
.size(); ++i
)
948 buckets
.values
[i
].update (*rate(), incr
);
952 ClassCHostPool::parse()
958 ClassCHostPool::keyAllocated (unsigned char const key
) const
960 return buckets
.indexUsed(buckets
.findKeyIndex (key
));
964 ClassCHostPool::makeHostKey (IPAddress
&src_addr
) const
966 /* FIXME INET6 : IPv6 requires a 64-128 bit result from this function */
967 if( !src_addr
.IsIPv4() )
970 /* Temporary bypass for IPv4-only */
972 src_addr
.GetInAddr(host
);
973 return (ntohl(host
.s_addr
) & 0xff);
977 ClassCHostPool::makeKey (IPAddress
&src_addr
) const
979 /* FIXME INET6 : IPv6 requires a 64-128 bit result from this function */
980 if( !src_addr
.IsIPv4() )
983 /* Temporary bypass for IPv4-only */
985 src_addr
.GetInAddr(net
);
986 return ( (ntohl(net
.s_addr
) >> 8) & 0xff);
989 DelayIdComposite::Pointer
991 ClassCHostPool::id(CompositeSelectionDetails
&details
)
993 if (rate()->restore_bps
== -1)
994 return new NullDelayId
;
996 unsigned int key
= makeKey (details
.src_addr
);
998 unsigned char host
= makeHostKey (details
.src_addr
);
1000 unsigned char hostIndex
;
1002 unsigned char netIndex
;
1004 if (keyAllocated (key
))
1005 netIndex
= buckets
.findKeyIndex(key
);
1007 netIndex
= buckets
.insert (key
);
1009 hostIndex
= buckets
.values
[netIndex
].hostPosition (*rate(), host
);
1011 return new Id (this, netIndex
, hostIndex
);
1015 ClassCHostPool::Id::operator new(size_t size
)
1017 DelayPools::MemoryUsed
+= sizeof (Id
);
1018 return ::operator new (size
);
1022 ClassCHostPool::Id::operator delete (void *address
)
1024 DelayPools::MemoryUsed
-= sizeof (Id
);
1025 ::operator delete (address
);
1028 ClassCHostPool::Id::Id (ClassCHostPool::Pointer aPool
, unsigned char aNet
, unsigned char aHost
) : theClassCHost (aPool
), theNet (aNet
), theHost (aHost
)
1032 ClassCHostPool::Id::bytesWanted (int min
, int max
) const
1034 return theClassCHost
->buckets
.values
[theNet
].individuals
.values
[theHost
].bytesWanted (min
, max
);
1038 ClassCHostPool::Id::bytesIn(int qty
)
1040 theClassCHost
->buckets
.values
[theNet
].individuals
.values
[theHost
].bytesIn (qty
);